原创文章,转载请注明出处
下例亮色部分分别是下载,复制备份,上传的方法,其他多余的代码为路径处理,可根据自己的情况处理:
如何登陆退出FTP请看上一篇,
类开始的全局变量
private static FTPClient ftpClient = new FTPClient();
private String fileUrl = "";
boolean flag = true;
private void auditPass4StaticPage(PageFile pageFile, Integer versioin) throws Exception {
String longPath = pageFile.getPath();//获取path和state_pathString lpath = longPath.substring(0, longPath.lastIndexOf("/"));
String path = lpath.substring(0, lpath.lastIndexOf("/"));//获得需要下载的压缩包所在的文件夹地址
Map<String, Object> domainMap = new HashMap<String, Object>();
String baselocalPath = System.getProperty("catalina.home");//"C:";\\\\Tomcat 8.0
String subPath = path.substring(path.lastIndexOf("/") + 1, path.length());
String fileName = subPath + ".zip";
String remotePath = path.substring(path.indexOf(".cn/") + 3);
if (remotePath != null && !remotePath.equals("")) {
//链接本地ftp
this.loginFtp(domainMap);
File localFile = new File(baselocalPath + remotePath);//在本地建立一个相同的文件目录
localFile.mkdirs();
String localPath = localFile.getAbsolutePath();//获得目录在本地的绝对路径
System.out.println(localPath);
FileOutputStream outputStream = new FileOutputStream(new File(localPath + "/" + fileName));//输出流
//调用下载方法下载文件到本地三个参数示例
// 1: /StaticPage/20170914/1505373329228 2: /StaticPage/20170914/1505373329228 3: java.io.FileOutputStream@59be2620
if (dsuccess) {//如果下载成功则解压上传
UnCompressFile.unZipFiles(localPath + "/" + fileName, localPath + "/" + subPath + "/");//解压
//退出本地的FTP
boolean close = AuditPageServiceImpl.closeConnections(ftpClient);
//获取远程FTP链接
String statePath = pageFile.getStaticPath();
String domainName = statePath.substring(0, statePath.indexOf("/"));//域名
domainMap.put("domainName", domainName);
Domain domain = auditPageDao.getDomainByName(domainName);
String userName = domain.getFtpAccount();
String pw = domain.getFtpPassword();
domainMap.put("userName", userName);
domainMap.put("pw", pw);
String toRemotePath = statePath.substring(statePath.indexOf("/"));
String dirPath = localPath + "/" + subPath;//解压后的文件夹路径
if (close) {
//链接远程FTP
this.loginFtp(domainMap);
//插码
String indexLocal = (dirPath + "/" + "index.html").replaceAll("\\\\", "/");
ResReviewHtmlDTO review = HtmlContentReviewUtil.reviewHtmlFile(indexLocal, true);
if (review.getMessage() != null) {
logger.error("解压后插码发生错误:" + review.getMessage());
throw new BusinessException("解压后插码发生错误,message=" + review.getMessage());
}
//XXX3.5、备份FTP历史数据进版本文件夹 :备份css、js、images、以及index.html或其他历史.html页
String hVersion = "V" + String.valueOf(versioin - 1);
String urlSuffix = pageFile.getUrlSuffix();
if (versioin != 1) {
String dirPathCss = toRemotePath + "/css";
String dirPathJs = toRemotePath + "/js";
String dirPathImages = toRemotePath + "/images";
String dirPathPage = toRemotePath + "/" + urlSuffix;
String toRemotePathCss = toRemotePath + "/" + hVersion + "/css";
String toRemotePathJs = toRemotePath + "/" + hVersion + "/js";
String toRemotePathImages = toRemotePath + "/" + hVersion + "/images";
String toRemotePathPage = toRemotePath + "/" + hVersion;
//参数示例:/chenyaoyu/SH/pc/diMJ5q/css /chenyaoyu/SH/pc/diMJ5q/V2/css 备份的文件夹以及他下边的文件
boolean cssSuccess = this.copyDirectiory(dirPathCss, toRemotePathCss, null);//备份css文件夹
boolean jsSuccess = this.copyDirectiory(dirPathJs, toRemotePathJs, null);//备份js文件夹
boolean imagesSuccess = this.copyDirectiory(dirPathImages, toRemotePathImages, null);//备份images文件夹
//同一个方法此处直接备份文件,参数示例:要备份文件/chenyaoyu/SH/pc/diMJ5q/index.html 备份到路径 /chenyaoyu/SH/pc/diMJ5q/V2 备份文件的别名 : index.html
boolean indexSuccess = this.copyDirectiory(dirPathPage, toRemotePathPage, urlSuffix);//备份index.html或其他历史页面if (!cssSuccess || !jsSuccess || !imagesSuccess || !indexSuccess) {
logger.error("备份正式FTP环境文件出错");
throw new BusinessException("备份正式FTP环境文件出错");
}
}
//上传
String afterDirPath = dirPath.replaceAll("\\\\", "/");
//要上传的地址:/chenyaoyu/SH/pc/diMJ5q 文件所在地址 C:/Tomcat 8.0/StaticPage/20170914/1505373329228/1505373329228 别名问题普通世通可忽略此参数 index.html
boolean upSuccess = this.uploadDirFiles(toRemotePath, afterDirPath, urlSuffix);if (!upSuccess) {
logger.error("上传文件到正式FTP时出错");
throw new BusinessException("上传文件到正式FTP时出错");
}
} else {
logger.debug("*******本地FTP关闭链接失败");
throw new BusinessException("本地FTP关闭链接失败");
}
} else {
logger.debug("*******从本地服务器下载出错");
throw new BusinessException("从本地服务器下载文件出错出错");
}
}
}
/**
* 方法用于从FTP服务器中下载文件
* @param ftpUrl :下载文件所处FTP中路径
* @param fileName :下载的文件名称
* @param outputStream :下载文件的输出流对象
* @return boolean :表示是否上传成功
*/
public boolean downloadFileFromFtp(String ftpUrl, String fileName,OutputStream outputStream) {
boolean bool = false;
try {
ftpClient.enterLocalPassiveMode();//避免:java.net.SocketTimeoutException: Read timed out
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//二进制方式读取
ftpClient.changeWorkingDirectory(ftpUrl);
FTPFile[] ftpFile = ftpClient.listFiles();
for (int i = 0; i < ftpFile.length; i++) {
if (fileName.equals(ftpFile[i].getName())) {
ftpClient.retrieveFile(new String(ftpFile[i].getName()
.getBytes("GBK"), "ISO-8859-1"), outputStream);
outputStream.flush();
outputStream.close();
}
}
bool = true;
} catch (IOException e) {
e.printStackTrace();
bool = false;
}
return bool;
}
/**
* 复制文件夹.
*
* @param sourceDir
* @param targetDir
* @throws IOException
*/
public boolean copyDirectiory(String sourceDir, String targetDir, String keyUrlSuffix) throws IOException {
// 新建目标目录
int reply = 0;
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
} else {
if (!ftpClient.changeWorkingDirectory(targetDir)) {
// 创建多层目录
Boolean flag = this.createMultiDir(ftpClient, targetDir);
if (!flag) {
return false;
}
ftpClient.changeWorkingDirectory(targetDir);
}
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
// 获取源文件夹当前下的文件或目录
// File[] file = (new File(sourceDir)).listFiles();
FTPFile[] ftpFiles = ftpClient.listFiles(sourceDir);
for (int i = 0; i < ftpFiles.length; i++) {
if (ftpFiles[i].isFile()) {
if (null != keyUrlSuffix && !keyUrlSuffix.equals("")) {
sourceDir = sourceDir.substring(0, sourceDir.lastIndexOf("/"));
}
copyFile(ftpFiles[i].getName(), sourceDir, targetDir);//如果是文件,调用复制文件方法复制
} else if (ftpFiles[i].isDirectory()) {
copyDirectiory(sourceDir + "/" + ftpFiles[i].getName(), targetDir + "/" + ftpFiles[i].getName(), keyUrlSuffix);//如果是文件夹,递归
}
}
}
return true;
}
/**
* 复制文件.
*
* @param sourceFileName
* @param sourceDir
* @param targetDir
* @throws IOException
*/
public boolean copyFile(String sourceFileName, String sourceDir, String targetDir) throws IOException {
ByteArrayInputStream in = null;
ByteArrayOutputStream fos = new ByteArrayOutputStream();
int reply = 0;
reply = ftpClient.getReplyCode();
try {
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
} else {
if (!ftpClient.changeWorkingDirectory(targetDir)) {
Boolean flag = this.createMultiDir(ftpClient, targetDir);// 创建多层目录
if (!flag) {
return false;
}
ftpClient.changeWorkingDirectory(targetDir);
}
//ftpClient.setBufferSize(1024 * 2);
ftpClient.changeWorkingDirectory(sourceDir);// 变更工作路径
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);// 设置以二进制流的方式传输
ftpClient.retrieveFile(new String(sourceFileName.getBytes("GBK"), "iso-8859-1"), fos);// 将文件读到内存中
in = new ByteArrayInputStream(fos.toByteArray());
if (in != null) {
ftpClient.changeWorkingDirectory(targetDir);
ftpClient.storeFile(new String(sourceFileName.getBytes("GBK"), "iso-8859-1"), in);
}
}
} finally {
// 关闭流
if (in != null) {
in.close();
}
if (fos != null) {
fos.close();
}
}
return true;
}
/**
* 上传ftp时若传输路径为多层目录创建
*
* @param ftpPath
* @param localDir
* @param urlSuffix
*/
@Async
public boolean uploadDirFiles(String ftpPath, String localDir, String urlSuffix) {
int reply = 0;
try {
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
} else {
if (!ftpClient.changeWorkingDirectory(ftpPath)) {
// 创建多层目录
Boolean flag = this.createMultiDir(ftpClient, ftpPath);
if (!flag) {
return false;
}
ftpClient.changeWorkingDirectory(ftpPath);
}
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
//InputStream input = new FileInputStream(new File(filePath));
//ftpClient.storeFile(fileName, input);//上传压缩包
String fileUrl = this.uploadDirectory(ftpClient, localDir, ftpPath, urlSuffix);
flag = true;
System.out.println(fileUrl);
//input.close();
ftpClient.logout();
}
} catch (Exception e) {
logger.error("审核时将上传到服务器中的文件读取出来存入ftp文件服务器时出现错误!", e.getMessage());
throw new BaseException(ExceptionCategory.Illegal_Parameter,
"将上传到服务器中的文件读取出来存入ftp文件服务器时出现错误!" + e.getMessage());
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException ioe) {
}
}
}
return true;
}
/***
* @上传文件夹
* @param localDirectory
* 当地文件夹
* @param remoteDirectoryPath
* Ftp 服务器路径 以目录"/"结束
* */
public String uploadDirectory(FTPClient ftpClient, String localDirectory, String remoteDirectoryPath, String urlSuffix) {
File src = new File(localDirectory);
String tmpDir = localDirectory.replace("\\", "/").substring(0, localDirectory.replace("\\", "/").lastIndexOf("/"));
//String childDir = localDirectory.replace("\\", "/").substring(localDirectory.replace("\\", "/").lastIndexOf("/"), localDirectory.replace("\\", "/").length());
try {
boolean isT = ftpClient.changeWorkingDirectory(remoteDirectoryPath);// 改变工作路径
if (!isT) {
this.createMultiDir(ftpClient, remoteDirectoryPath);
// logger.info(remoteDirectoryPath + "创建文件夹成功!");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
File[] allFile = src.listFiles();
if (allFile != null) {
for (int currentFile = 0; currentFile < allFile.length; currentFile++) {
if (!allFile[currentFile].isDirectory()) {
String srcName = allFile[currentFile].getPath().toString();
String tempPath = allFile[currentFile].getParent().toString().replace("\\", "/").replace(tmpDir.replace("\\", "/"), "");
//此处的判断是因为文件夹特殊的结构:文件中包括一个index.html文件和三个包含文件的文件夹,都要保存在特定的版本文件夹下,可根据自己文件夹的结构做特殊处理
if (srcName.indexOf("index.html") >= 0 && flag == true) {
fileUrl = remoteDirectoryPath + "/" + ShortUrlUtil.getShortUrl(remoteDirectoryPath) + urlSuffix;
//String newSrcName= srcName.substring(0, srcName.lastIndexOf("\\"))+"\\"+urlSuffix;
this.uploadFile(ftpClient, new File(srcName), remoteDirectoryPath, urlSuffix);
flag = false;
} else {
this.uploadFile(ftpClient, new File(srcName), remoteDirectoryPath + tempPath, urlSuffix);
}
} else {
uploadDirectory(ftpClient, allFile[currentFile].getPath().toString(), remoteDirectoryPath, urlSuffix);//是文件夹则迭代
}
}
} else {
this.uploadFile(ftpClient, new File(localDirectory), remoteDirectoryPath, urlSuffix);
fileUrl = remoteDirectoryPath + localDirectory.substring(localDirectory.lastIndexOf("/"), localDirectory.length());
}
return fileUrl;
}
/***
* 上传Ftp文件
*
* @param localFile
* 当地文件
* @param romotUpLoadePath 上传服务器路径
* - 应该以/结束
* */
public boolean uploadFile(FTPClient ftpClient, File localFile, String romotUpLoadePath, String urlSuffix) {
BufferedInputStream inStream = null;
boolean success = false;
try {
try {
boolean isT = ftpClient.changeWorkingDirectory(romotUpLoadePath);// 改变工作路径
if (!isT) {
this.uploadDirectory(ftpClient, romotUpLoadePath);
ftpClient.changeWorkingDirectory(romotUpLoadePath);// 改变工作路径
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
inStream = new BufferedInputStream(new FileInputStream(localFile));
if (localFile.getName().equals("index.html")) {
success = ftpClient.storeFile(urlSuffix, inStream);
} else {
success = ftpClient.storeFile(localFile.getName(), inStream);
}
if (success == true) {
return success;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inStream != null) {
try {
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return success;
}
上边几个方法中用到的工具类:如创建多层目录等:
/**
* 创建多层目录
*
* @param ftpClient
* @param multiDir
* @return
* @throws IOException
*/
public boolean createMultiDir(FTPClient ftpClient, String multiDir) throws IOException {
boolean bool = false;
String[] dirs = multiDir.split("/");
ftpClient.changeWorkingDirectory("/");
for (int i = 1; dirs != null && i < dirs.length; i++) {
if (!ftpClient.changeWorkingDirectory(dirs[i])) {
if (ftpClient.makeDirectory(dirs[i])) {
if (!ftpClient.changeWorkingDirectory(dirs[i])) {
return false;
}
}
}
bool = true;
}
return bool;
}
public boolean uploadDirectory(FTPClient ftp, String localDirectory) {
String remoteDirectoryPath = "";
// 登录FTP
try {
String[] mk = localDirectory.split("/");
for (int i = 0; i < mk.length; i++) {
try {
remoteDirectoryPath = remoteDirectoryPath + mk[i] + "/";
boolean flag = ftp.changeWorkingDirectory(remoteDirectoryPath);
if (!flag) {
ftp.makeDirectory(remoteDirectoryPath);
}
} catch (IOException e) {
return false;
}
}
} catch (Exception e) {
return false;
}
return true;
}