关于如何建立两个ftp连接传输文件以及其中踩坑记录
1.创建一个连接FTP的工具类FTPUtil.java
package com.metarnet.ftp.util;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.util.Properties;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;
public class FTPUtil {
private static Logger logger = Logger.getLogger(FTPUtil.class);
/**
* 获取FTPClient对象
* @param ftpHost FTP主机服务器
* @param ftpPassword FTP 登录密码
* @param ftpUserName FTP登录用户名
* @param ftpPort FTP端口 默认为21
* @return
*/
public static FTPClient getFTPClient(String ftpHost, String ftpPassword,
String ftpUserName, int ftpPort) {
FTPClient ftpClient = null;
try {
ftpClient = new FTPClient();
ftpClient .setControlEncoding("UTF-8");//这里一定要设置字符编码,不然无法读取中文路径
ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
logger.info("未连接到FTP,用户名或密码错误。");
ftpClient.disconnect();
} else {
logger.info("FTP连接成功。");
}
} catch (SocketException e) {
e.printStackTrace();
logger.info("FTP的IP地址可能错误,请正确配置。");
} catch (IOException e) {
e.printStackTrace();
logger.info("FTP的端口错误,请正确配置。");
}
return ftpClient;
}
}
2.创建两个ftp链接
FTPClient ftpClient1 = getFTPClient(host1,port1,account1,password1);//源ftp
FTPClient ftpClient2 = getFTPClient(host2,port2,account2,password2);//目标ftp
boolean b1 = ftpClient1.changeWorkingDirectory("源ftp文件目录")//使用changeWorkingDirectory切换到指定目录
if(!b1){ //如果b1为false ,说明找不到源ftp文件目录,就别执行传输了
ftpClient2.disconnect();
ftpClient1.disconnect();
boolean b2 = ftpClient2.changeWorkingDirectory("目标ftp文件目录")//使用changeWorkingDirectory切换到指定目录
if(!b2){ // 如果b2为false ,说明找不到目标ftp文件目录,可以创建这个目录
//坑1:ftp创建多级目录必须要循环创建,不然创建不成功而且不会报错
ftpClient2.makeDirectory("目标ftp文件目录");
b2 = makeDir(ftpClient2,"目标ftp文件目录");
InputStream inputstream1 = ftpClient1.retrieveFileSteam("文件名");//根据文件名获取源ftp文件输入流
//坑2:inputstream1.available();每次获取的文件大小不同,不清楚什么原因
if(inputstream1 != null && b2){
//开始copy文件
//坑3:不要在这之前执行ftpClient2.retrieveFileSteam("文件名");//可能你会用这个方法判断目标路径是否已经存在文件(如果存在可以不用再重复传输),但是这样操作后再执行下面的会一直为false
ftpClient2.storeFile方法 copySucceed
boolean copySucceed = ftpClient2.storeFile("文件名",inputstream1);
if(!copySucceed){
copySucceed = ftpClient2.storeFile(new String("文件名".getBytes(”uft-8“),"iso-8859-1"),inputstream1);
boolean makeDir(FTPClient ftp,string path) throws IOEception{
// 分割
String[] paths = path.split("/");
// 创建成功标识
boolean isMakeSucess = false;
// 遍历每一级路径
for (String str : paths) {
// 切换目录,根据切换是否成功判断子目录是否存在
boolean changeSuccess = ftp.changeWorkingDirectory(str);
// 该级路径不存在就创建并切换
if (!changeSuccess) {
isMakeSucess = ftp.makeDirectory(str);
ftp.changeWorkingDirectory(str);
}
}
return isMakeSucess;