/**
* 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,否則會無效。
