本文所使用的環境爲:
- ftp服務器:XP系統+Server-u搭建的FtpServer;
- ftp客戶端:XP系統+tomcat+ApacheFtpClient;
Server-u搭建的ftp服務器默認爲UTF-8的編碼,如果希望使用系統默認編碼需要在設置中修改:百度經驗修改server-u搭建的ftp服務器的編碼
FtpUtil:
public class ApacheFtpUtil {
private static ApacheFtpUtil ApacheFtpUtil = null;
private FTPClient ftp = null;
boolean _isLogin = false;
//初始化方法;
public static ApacheFtpUtil getInstance() {
if (ApacheFtpUtil == null) {
ApacheFtpUtil = new ApacheFtpUtil();
}
return ApacheFtpUtil;
}
private String ip;
private int port;
private String uname;
private String pass;
/**
* ftp 匿名登錄
*
* @param ip ftp服務地址
* @param port 端口號
*/
public boolean login(String ip, int port) {
//如果沒有設置ftp用戶可將username設爲anonymous,密碼爲任意字符串
return login(ip, port, "anonymous", "");
}
/**
* ftp登錄
*
* @param ip ftp服務地址
* @param port 端口號
* @param uname 用戶名
* @param pass 密碼
*/
public boolean login(String ip, int port, String uname, String pass) {
this.ip = ip;
this.port = port;
this.uname = uname;
this.pass = pass;
ftp = new FTPClient();
// boolean flag=false;
try {
// 連接
ftp.connect(ip, port);
_isLogin = ftp.login(uname, pass);
System.out.println("ftp:" + (_isLogin ? "登錄成功" : "登錄失敗"));
//判斷是否支持utf-8,如果支持則設置連接編碼爲UTF-8
// if(FTPReply.isPositiveCompletion(ftp.sendCommand("OPTS UTF-8","ON"))){
// ftp.setControlEncoding("UTF-8");
// }else{
//設置連接的編碼爲GBK;
ftp.setControlEncoding("GBK");
// }
// 檢測連接是否成功
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
System.err.println("FTP服務器拒絕連接 ");
return false;
}
return true;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
/**
* 下載文件
*
* @param ftpDirName ftp目錄名
* @param ftpFileName ftp文件名
* @param localFileFullName 本地文件名
* @return
* @author xxj
*/
public boolean downloadFile(String ftpDirName,
String ftpFileName, String localFileFullName) {
if (!ftp.isConnected()) {
//判斷ftp連接是否關閉,如果關閉了則重新登陸,避免大批次的操作時出現連接中斷;
login(ip, port, uname, pass);
}
ftp.enterLocalPassiveMode();
try {
if ("".equals(ftpDirName))
ftpDirName = "/";
// String dir = new String(ftpDirName.getBytes("UTF-8"), "iso-8859-1");
String dir = "";
//判斷當前是本地測試還是生產環境
//由於我本地都是utf8的編碼,而生產都是GBK所以需要進行特殊處理
if("1".equals(PropertiesLoader.ISTEST)){
dir = new String(ftpDirName.getBytes("UTF-8"), "ISO-8859-1");
}else{
dir = new String(ftpDirName.getBytes("GBK"), "ISO-8859-1");
}
if (!ftp.changeWorkingDirectory(dir)) {
System.out.println("切換目錄失敗:" + ftpDirName);
System.out.println("轉換後路徑:" + dir);
return false;
}
FTPFile[] fs = ftp.listFiles();
String fileName = "";
if("1".equals(PropertiesLoader.ISTEST)){
fileName = new String(ftpFileName.getBytes("UTF-8"), "iso-8859-1");
}else{
fileName = new String(ftpFileName.getBytes("GBK"), "ISO-8859-1");
}
for (FTPFile ff : fs) {
if (ff.getName().equals(fileName)) {
File file = createFile(localFileFullName, true);
FileOutputStream is = new FileOutputStream(file);
ftp.retrieveFile(ff.getName(), is);
is.close();
System.out.println("下載ftp文件已下載:" + localFileFullName);
return true;
}
}
System.out.println("下載ftp文件失敗:" + ftpFileName + ";目錄:" + ftpDirName);
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
個人拙見:ftp連接過程中,傳輸數據時會將數據轉換爲ISO-8859-1的字節流,所以需要事先將中文轉換成ISO-8859-1的編碼,同時告知ftpServer以何種格式的編碼解碼;(如有錯誤望在評論處指出,感謝!!!)