Appache Ftp使用
前言
之前一直使用的是jdk自带的ftp功能进行文件上传、下载、复制等功能,但是发现本功能和jdk版本相关,升级jdk版本导致的结果就是ftp工具类直接报错,无法使用,经过观察jdk源码发现,ftp中部分方法在新版本已经不存在,这种情况下,就不得不考虑寻找新的FTP工具包来重写FTP工具类,网上评价最好的当属appache的ftp工具包,所以,今天就简单的介绍下本工具类
。
准备
- 了解linux系统ftp
这里我只介绍工具类可能会用的一些说明。ftp连接主要是通过连接地址、端口号(默认端口21)、用户名、密码进行连接。默认设置:连接方式是ASCII方式,最大连接数是200个,空闲操作自动断开连接是600秒。
说明:默认的传输方式是ASCII码传输或者自动,部分编译过的程序上传就会出错,例如通过ZEND加密,或者其他加密,ASCII码传输的时候,编码方式是7位ASCII编码,如果你不是这种编码的数据,就会造成数据的损坏,会缺少1位,所以做文件传输的时候,一般都会选二进制进行传输,这样可以保证源文件的完整。
- 了解Appache Ftp可以实现那些功能
通过查看Appache中的api,基本支持大部分ftp的功能,如:ftp连接、切换ftp路径、获取文件列表,创建文件夹、重命名文件、获取文件流、上传文件等等。将这些功能进行封装后,基本可以满足ftp应用的大部分使用场景,如多线程下批量上传多个文件到新路径。
- 引入JAR
当前我这边使用的是最新的3.5版本(推荐使用最新版本)
maven引入
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.5</version>
</dependency>
ivy引入
<dependency org="commons-net" name="commons-net" rev="3.5" />
gradle引入
compile("commons-net:commons-net:3.5")
备注:本处就引入了ftp包,后续用的日志等其余的包请自行引入。
编写ftp方法基本方法(进行封装)
- 创建FtpFileUtil对象()
public FtpFileUtil() { if (null == ftpClient) { ftpClient = new FTPClient(); } }
- 获取ftp连接
/**
* 方法 connect
*
* @param hostname ftp主机Ip
* @param username 端口
* @param username 用户名
* @param password 用户密码
* @return @throws Exception
*/
public FTPClient connect(String hostname, int port, String username, String password) {
log.info("正在连接: " + hostname + ", 请等待...");
String loginfo = "";
try {
// 设置编码格式,必须连接之前设置,否则无效
ftpClient.setControlEncoding(encoding);
// 连接FTP服务器
ftpClient.connect(hostname, port);
// 登录
ftpClient.login(username, password);
// 设置文件传输类型为二进制
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
} catch (IOException e) {
loginfo = "连接主机:" + hostname + "过程失败!请检查ftp请求连接信息是否正确!";
throw new RuntimeException(loginfo, e);
} catch (Exception e) {
throw new RuntimeException(loginfo, e);
}
log.info("连接主机:" + hostname + "成功!");
return ftpClient;
}
- 断开ftp连接
/** * 关闭ftp连接 */ public void ftpDisconnect() { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); log.info("与ftp断开连接成功"); } catch (IOException e) { throw new RuntimeException( "与ftp主机断开连接失败!", e); } } }
- 返回根路径
/**
* 返回根路径
*
* @return 返回操作结果
*/
public boolean returnRootDirectory() {
try {
String currentFilePath = ftpClient.printWorkingDirectory();
StringTokenizer s = new StringTokenizer(currentFilePath, "/");
int length = s.countTokens();
for (int i = length ; i > 0; i--) {
ftpClient.changeToParentDirectory();
}
return true;
} catch (IOException e) {
throw new RuntimeException( "返回根路径过程出错!", e);
}
}
- 获取当前路径
/** * 获取当前ftp工作路径 * * @return 返回当前ftp路径 */ public String getWorkingDirectory() { try { return ftpClient.printWorkingDirectory(); } catch (IOException e) { throw new RuntimeException( "获取当前工作路径过程出错", e); } }
- 删除一个文件
/** * 删除一个文件 * * @param ftpFilePath 文件夹路径 * @param fileName 删除的文件名称 */ public boolean deleteFile(String fileName, String ftpFilePath) { boolean flag = true; try { ftpClient.changeWorkingDirectory(new String(ftpFilePath.getBytes(encoding), "iso-8859-1")); flag = ftpClient.deleteFile(fileName); if (flag) { log.info("删除文件" + fileName + "成功"); } else { log.error("删除文件" + fileName + "失败"); } } catch (IOException e) { throw new RuntimeException("删除文件" + fileName + "失败", e); } finally { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException e) { throw new RuntimeException("与ftp主机断开连接失败!", e); } } } return flag; }
- 校验文件夹是否存在
/** * 检查文件夹是否存在 * * @param ftpFilePath 文件夹路径 * @return */ public boolean isDirExist(String ftpFilePath) { log.info("校验是否存在文件夹:" + ftpFilePath + ",请等待..."); boolean isDirExist = false; try { int retCode = ftpClient.cwd(ftpFilePath); isDirExist = FTPReply.isPositiveCompletion(retCode); log.info("校验是否存在文件夹" + ftpFilePath + "结束,结果为:" + isDirExist); return isDirExist; } catch (Exception e) { log.error("校验文件夹" + ftpFilePath + "是否存在过程出错", e); return false; } }
- 还要一个切换路径方法,因为单独切换路径一般意义不大,所以都是封装到其他方法中配合使用
// 转移工作目录至指定目录下 boolean change = ftpClient.changeWorkingDirectory(ftpFilePath);
结束
本文主要是介绍了下ftp该怎么用,之后封装了部分简单ftp方法,其实还有一些其余的方法,可以自行参考api进行方法补充。下篇文章主要是将会介绍,ftp文件(/批量)上传/下载、ftp文件列表一些封装方法介绍。