本文所使用的环境为:
- 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以何种格式的编码解码;(如有错误望在评论处指出,感谢!!!)