java ftpclient 池_apache-commons commons-pool2整合 commons-net 自定 FTPClient对象池

commons-net 包介绍

commons-net 是 apachecommons 用于网络的工具包,它实现了一些常见的网络工具,如 smtp,pop3,telnet,ftp,udp 等,本文主要使用它的 ftp 工具。

使用 FTP 工具时的问题

在使用 commons-net 提供的 ftp 工具的时候 ,发现每次都要走一遍完整的连接,登录流程。每次都创建连接的话,很快就会把连接耗光,如果使用单例,则效率过低,因为只有一个连接,所以考虑用对象池的方式。

自已定义对象池的话,我之前有弄过,但要考虑好多的问题。像线程池一样,需要考虑核心对象数、最大对象数、何时创建对象 、及队列等,这时可以使用 apache 的 commons-pool2 来做一个对象池。

重要说明 : FTPClient 每次使用都需要重新连接,不然它会自动断开连接,使用会直接返回 421 ,本文章只是给个使用 commons-pool2 对象池的示例。

如何使用 commons-pool2

可以这么想,如果我要做个对象池的工具给别人用,首先要考虑的是池子里装的什么,用户要如何创建池子里的对象,然后提供方法借对象和回收对象,我可以把池子中的对象抽象出来,由一个工厂统一管理,用户的对象从我的通用对象继承或实现,或使用聚合方式 。

其实 spring-data-redis 已经给我们一个完整的使用 commons-pool2 的例子,它就是用的 commons-pool2 ,它的池中对象是 redis 连接,有兴趣可以去瞧瞧。

定义池中对象 FTPClient 的扩展对象

因为 FTPClient 的功能太过简单,连多层目录时自己创建目录都不会,所以有必要给它包装一下,这里你可以扩展常用到的方法。

import org.apache.commons.net.ftp.FTP;

import org.apache.commons.net.ftp.FTPClient;

import org.apache.commons.net.ftp.FTPFile;

@Slf4j

public class FtpClientExtend {

private FTPClient ftpClient ;

public FtpClientExtend(FTPClient ftpClient) {

this.ftpClient = ftpClient;

}

/**

* 列出文件列表

* @param filePath

* @return

* @throws IOException

*/

public FTPFile[] listFiles(String filePath) throws IOException {

return ftpClient.listFiles(filePath);

}

/**

* 下载文件

* @param filePath

* @return

*/

public InputStream downloadFile(String filePath) throws IOException {

return ftpClient.retrieveFileStream(filePath);

}

/**

* 存储文件

* @param s

* @param inputStream

*/

public void uploadFile(String filePath, InputStream inputStream) throws IOException {

File targetFilePath = new File(filePath);

Path path = targetFilePath.getParentFile().toPath();

Iterator iterator = path.iterator();

StringBuffer root = new StringBuffer("");

while (iterator.hasNext()){

Path next = iterator.next();

root.append("/").append(next);

//尝试切入目录

boolean success = ftpClient.changeWorkingDirectory(root.toString());

if(!success){

int mkd = ftpClient.mkd(next.toString());

ftpClient.changeWorkingDirectory(root.toString());

}

}

ftpClient.enterLocalPassiveMode();

ftpClient.setControlEncoding("UTF-8");

ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

boolean storeFileResult = ftpClient.storeFile(targetFilePath.getName(), inputStream);

if (storeFileResult) {

log.debug("上传文件:" + filePath + ",到目录:" + ftpClient.printWorkingDirectory() + " 成功");

}else{

log.debug("上传文件:" + filePath + ",到目录:" + ftpClient.printWorkingDirectory() + " 失败");

}

}

}

使用聚合包裹池中对象

这个包裹对象的类才是工厂真正产生在池中的类,文末给出图示

import org.apache.commons.pool2.PooledObjectFactory;

import org.apache.commons.pool2.impl.GenericObjectPool;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

public class FtpClientPool extends GenericObjectPool {

public FtpClientPool(PooledObjectFactory factory) {

super(factory);

}

public FtpClientPool(PooledObjectFactory factory, GenericObjectPoolConfig config) {

super(factory, config);

}

}

建立创建对象的工厂

import org.apache.commons.net.ftp.FTPClient;

import org.apache.commons.pool2.BasePooledObjectFactory;

import org.apache.commons.pool2.PooledObject;

import org.apache.commons.pool2.impl.DefaultPooledObject;

public class FtpClientFactory extends BasePooledObjectFactory {

@Value("${ftp.host:localhost}")

private String host;

@Value("${ftp.port:21}")

private int port;

@Value("${ftp.username:ftpadmin}")

private String username;

@Value("${ftp.password:salt202}")

private String password;

@Override

public FtpClientExtend create() throws Exception {

FTPClient ftpClient = new FTPClient();

ftpClient.connect(host,port);

boolean login = ftpClient.login(username, password);

if(!login){

throw new RuntimeException("ftp 登录失败,检查用户名密码是否正确["+host+":"+port+"]["+username+"]["+password+"]");

}

return new FtpClientExtend(ftpClient);

}

@Override

public PooledObject wrap(FtpClientExtend ftpClientExtend) {

return new DefaultPooledObject(ftpClientExtend);

}

}

使用方法

@Autowired

private FtpClientPool ftpClientPool;

public void method(){

FtpClientExtend ftpClientExtend = null;

try{

ftpClientExtend = ftpClientPool.borrowObject();

}finally{

if(ftpClientExtend != null) {

ftpClientPool.returnObject(ftpClientExtend);

}

}

}

原理图示

1460000020378078?w=623&h=254

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值