寫個功能要從ftp服務下載下傳檔案,在本地的ftp服務一切ok(window環境),但是在Linux環境發現不管切換到哪個目錄,擷取什麼檔案,調用FTPClient.listFiles()方法時傳回的始終為空,但是代碼又運作正常沒有異常抛出。然後斷點ftp.getReplyCode()也傳回230登陸成功.
解決的方很簡單,
在調用FTPClient.listFiles()方法前,先調用FTPClient.enterLocalPassiveMode();就可以了。
/**
* 從FTP伺服器上下載下傳檔案
* @param ftpDirectoryAndFileName ftp伺服器檔案路徑,以/dir形式開始
* @param localDirectoryAndFileName 儲存到本地的目錄
* @return
*/
public boolean get(String ftpDirectoryAndFileName, String localDirectoryAndFileName) {
File file=new File(localDirectoryAndFileName);
if (!file.exists())file.mkdirs();
if (!ftpClient.isConnected()) {
return false;
}
ftpClient.enterLocalPassiveMode(); // Use passive mode as default
try {
// 将路徑中的斜杠統一
char[] chars = ftpDirectoryAndFileName.toCharArray();
StringBuffer sbStr = new StringBuffer(256);
for (int i = 0; i < chars.length; i++) {
if ('\\' == chars[i]) {
sbStr.append('/');
} else {
sbStr.append(chars[i]);
}
}
ftpDirectoryAndFileName = sbStr.toString();
String filePath = ftpDirectoryAndFileName.substring(0, ftpDirectoryAndFileName.lastIndexOf("/"));
String fileName = ftpDirectoryAndFileName.substring(ftpDirectoryAndFileName.lastIndexOf("/") + 1);
this.changeDir(filePath);
ftpClient.retrieveFile(new String(fileName.getBytes(), "iso-8859-1"),
new FileOutputStream(localDirectoryAndFileName)); // download
// file
System.out.println(ftpClient.getReplyString()); // check result
System.out.println("線程"+Thread.currentThread().getName()+"從ftp伺服器上下載下傳檔案:" + ftpDirectoryAndFileName + ", 儲存到:" + localDirectoryAndFileName);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
調用FTPClient.enterLocalPassiveMode();這個方法的意思就是每次資料連接配接之前,ftp client告訴ftp server開通一個端口來傳輸資料。為什麼要這樣做呢,因為ftp server可能每次開啟不同的端口來傳輸資料,但是在linux上,由于安全限制,可能某些端口沒有開啟,是以就出現阻塞。