整理一个ftp上传下载的工具类,转编码的问题经测试都已经很好的解决,我这里用的ftp为Windows系统下,Linux下的ftp操作写法不一样,下次有用到再整理:
FtpUtil
- jar
commons-net-3.3.jar
- maven依赖
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.1</version>
</dependency>
public class FtpUtil {
private final static Log logger = LogFactory.getLog(FtpUtil.class);
/**
* 获取FTPClient对象
*
* @param ftpHost
* FTP主机服务器
* @param ftpPassword
* FTP 登录密码
* @param ftpUserName
* FTP登录用户名
* @param ftpPort
* FTP端口 默认为21
* @return
*/
public static FTPClient getFTPClient(String ftpHost, String ftpUserName,
String ftpPassword, int ftpPort) {
FTPClient ftpClient = new FTPClient();
try {
ftpClient = new FTPClient();
ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
logger.info("未连接到FTP,用户名或密码错误。");
ftpClient.disconnect();
} else {
logger.info("FTP连接成功。");
}
} catch (SocketException e) {
e.printStackTrace();
logger.info("FTP的IP地址可能错误,请正确配置。");
} catch (IOException e) {
e.printStackTrace();
logger.info("FTP的端口错误,请正确配置。");
}
return ftpClient;
}
/*
* 从FTP服务器下载文件
*
* @param ftpHost FTP IP地址
*
* @param ftpUserName FTP 用户名
*
* @param ftpPassword FTP用户名密码
*
* @param ftpPort FTP端口
*
* @param ftpPath FTP服务器中文件所在路径 格式: ftptest/aa
*
* @param localPath 下载到本地的位置 格式:H:/download
*
* @param fileName 文件名称
*/
public static void downloadFtpFile(String ftpHost, String ftpUserName,
String ftpPassword, int ftpPort, String ftpPath, String localPath,
String fileName) {
FTPClient ftpClient = null;
try {
String ftpPath2 = new String(ftpPath.getBytes("GBK"),"iso-8859-1");
ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
ftpClient.setControlEncoding("UTF-8"); // 中文支持
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
boolean flag1 = ftpClient.changeWorkingDirectory(ftpPath2);
if (!flag1) {
logger.error("没有找到" + ftpPath + "---该路径");
return;
}
File localFile = new File(localPath + File.separatorChar + new String(fileName.getBytes("GBK"),"UTF-8"));
OutputStream os = new FileOutputStream(localFile);
//复制文件流
boolean flag2 = ftpClient.retrieveFile(new String(fileName.getBytes("GBK"),"iso-8859-1"), os);
if (!flag2) {
logger.error("没有找到" + fileName + "---该文件");
localFile.delete();
}
os.close();
ftpClient.logout();
} catch (FileNotFoundException e) {
logger.error("没有找到" + ftpPath + "文件");
e.printStackTrace();
} catch (SocketException e) {
logger.error("连接FTP失败.");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
logger.error("文件读取错误。");
e.printStackTrace();
}
}
/**
* 上传部分代码如下:
* @param ftpHost:文件服务器主机地址
* @param ftpPort:文件服务器端口号
* @param ftpUserName:用户名
* @param ftpPassword:密码
* @param path:文件要保存的路径
* @param filename:文件名字
* @param localPath:本地文件路径
* @return
*/
public static void uploadToFTPServer(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword, String path,
String filename, String localPath) {
FTPClient ftpClient = null; // 创建一个客户端实例
try {
path = new String(path.getBytes("GBK"),"iso-8859-1");
ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
// ftp.makeDirectory("bbb");//创建文件目录
ftpClient.changeWorkingDirectory(path);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 设置文件以二进制的形式上传,防止文件内容乱码出现
// 设置文件名字的编码格式为iso-8859-1,因为FTP上传的时候默认编码为iso-8859-1,解决文件名字乱码的问题
filename = new String(filename.getBytes("GBK"), "iso-8859-1");
InputStream in = new FileInputStream(new File(localPath));
ftpClient.storeFile(filename, in); // 开始上传文件
in.close();// 关闭文件输入流
ftpClient.logout();// 断开和ftp服务器之间的连接
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException ioe) {
}
}
}
}
public static String getFullCurrentWorkingDirectory(FTPClient ftpClient) throws IOException{
String[] dir = ftpClient.doCommandAsStrings("pwd","");
System.out.println(dir[0]);
Pattern p=Pattern.compile("\"(.*?)\"");
Matcher m=p.matcher(dir[0]);
String fullPath = null;
if(m.find()){
fullPath = m.group(0).replace("\"","");
}
return fullPath;
}
public static String getRelativeCurrentWorkingDirectory(FTPClient ftpClient) throws IOException{
String[] dir = ftpClient.doCommandAsStrings("pwd","");
System.out.println(dir[0]);
return "";
}
public static void showFile(FTPClient ftpClient) throws IOException{
FTPFile[] files = ftpClient.listFiles();
for(FTPFile f : files){
if(f.isDirectory()){
System.out.println(f.getName()+"-----directory");
ftpClient.changeWorkingDirectory(f.getName());
showFile(ftpClient);
}else if(f.isFile()){
System.out.println(f.getName());
}
}
ftpClient.changeToParentDirectory();
}
}
需要几个坑
- ftp的路径出错或文件不存在的情况话下载会出现空文件,我这里的处理方式也很简单,失败即删了本地新建的文件。
- 中文路径和中文文件名的处理情况不太一样,iso-8859-1是ftp默认的编码格式,路径转换了就行,但是文件名要特别注意的是下载时,new本地文件时给的文件名一定得是中文,而retrieveFile进行ftp文件操作时得转换编码对应。
- setFileType的方式可有效防止文件内容乱码