/**
* Description: 从FTP服务器下载文件
* @Version1.0 Jul 27, 2008 5:32:36 PM by 崔红保(cuihongbao@d-heaven.com)创建
* @param url FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param remotePath FTP服务器上的相对路径
* @param fileName 要下载的文件名
* @param localPath 下载后保存到本地的路径
* @return
*/
public static boolean downFile(String ip, int port,String username, String password, String remotePath,String fileName,String localPath) {
boolean success = false;
FTPClient ftpc = new FTPClient();
String LOCAL_CHARSET="GBK";
try {
logger.info("连接ftp----");
//ftpc.setCharset(Charset.forName("GBK"));
////ftp中文编码设置
ftpc.setControlEncoding("GBK");
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
conf.setServerLanguageCode("zh");
ftpc.configure(conf);
int reply;
ftpc.connect(ip,port);
logger.info("--------------连接ftp成功--------------");
//如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftpc.login(username, password);//登录
reply = ftpc.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpc.disconnect();
return success;
}
logger.info("登录ftp成功!!!!!!!!!!!!!!");
ftpc.changeWorkingDirectory(remotePath);//转移到FTP服务器目录
ftpc.enterLocalPassiveMode(); //设置被动模式
ftpc.setFileType(ftpc.BINARY_FILE_TYPE); //设置下载文件为二进制模式
ftpc.setFileTransferMode(ftpc.STREAM_TRANSFER_MODE); ///传输文件为流的形式
logger.info("切换路径:"+remotePath);
FTPFile[] fs = ftpc.listFiles();
////判断本地的日期路径是否存在
File file = new File(localPath);
//判断文件夹是否存在,如果不存在则创建文件夹
if (!file.exists()) {
file.mkdir();
}
///循环下载
for(FTPFile ff:fs){
logger.info("文件名称:"+ff.getName());
File localFile = new File(localPath+"/"+ff.getName());
OutputStream is = new FileOutputStream(localFile);
ftpc.retrieveFile(new String(ff.getName().getBytes("utf-8"), "GBK"), is);
is.close();
logger.info("下载完毕----");
}
ftpc.logout();
success = true;
} catch (IOException e) {
//e.printStackTrace();
logger.error("ftp下载报错", e);
} finally {
if (ftpc.isConnected()) {
try {
ftpc.disconnect();
} catch (IOException ioe) {
}
}
}
return success;
}
如上代码,ftp上传下载其实很简单,但是有时候相信有的人很困惑,为什么服务器上的路径是对的,反而上传或者下载文件都是失败的或者获取为空。
这是因为ftp的ip的问题,如果ip没有经过防火墙的路由,我们上传下载,直接不需要设置,因为ftpclient默认为主动模式,客户端主动向服务器端发起申请。
但是如果ip穿过防火墙,经过路由了,这时候我们需要注意了,我们再去使用默认下载或者上传,会发生问题。这时候我们需要使用被动模式了。
enterLocalPassiveMode:设置客户端PASV模式
static int PASSIVE_LOCAL_DATA_CONNECTION_MODE
enterLocalActiveMode:设置客户端PORT模式
static int ACTIVE_LOCAL_DATA_CONNECTION_MODE
FTP传输有两种模式:主动模式(PORT)和被动模式(PASV)
另外,ftp下载gbk编码也需要有很多注意的地方,比如要包含
ftpc.setControlEncoding("GBK"); FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX); conf.setServerLanguageCode("zh"); ftpc.configure(conf);
另外FTPClient也需要配置一下,如下:
ftpc.setFileType(ftpc.BINARY_FILE_TYPE); //设置下载文件为二进制模式 ftpc.setFileTransferMode(ftpc.STREAM_TRANSFER_MODE); ///传输文件为流的形式
注意上面设置ftpc.BINARY_FILE_TYPE和ftpc.STREAM_TRANSFER_MODE,这里的ftpc都是声明的FTPClient,不能直接写FTPClient,否则会无效。