Java 自定义FTP连接池

转自:https://blog.csdn.net/eakom/article/details/79038590

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/eakom/article/details/79038590

一、引入FTP包和连接池包

<!-- ftp连接start -->
<dependency>
    <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.5</version> </dependency> <!-- ftp连接start --> <!-- 自定义连接池 start--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.5.0</version> </dependency> <!-- 自定义连接池 end-->
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

二、在项目根路径新建一个配置文件,把连接池配置属性和FTPClient属性配置在配置文件中,ftpClient.properties配置文件如下

#FTP连接池配置
#最大数
ftpClient_maxTotal=50
#最小空闲
ftpClient_minIdle=10 #最大空闲 ftpClient_maxIdle=100 #最大等待时间 ftpClient_maxWait=3000 #池对象耗尽之后是否阻塞,maxWait<0时一直等待 ftpClient_blockWhenExhausted=true #取对象是验证 ftpClient_testOnBorrow=true #回收验证 ftpClient_testOnReturn=true #创建时验证 ftpClient_testOnCreate=true #空闲验证 ftpClient_testWhileIdle=false #后进先出 ftpClient_lifo=false #FTP连接属性配置 #ip ftpClient_host=192.168.158.98 #端口 ftpClient_port=21 #登录名 ftpClient_username=ftpadmin #密码 ftpClient_pasword=eakom123456 #连接是否为主动模式 ftpClient_passiveMode=true #编码 ftpClient_encoding=UTF-8 #超时时间 ftpClient_clientTimeout=600 #线程数 ftpClient_threaNum=1 #文件传送类型 #0=ASCII_FILE_TYPE(ASCII格式) 1=EBCDIC_FILE_TYPE 2=LOCAL_FILE_TYPE(二进制文件) ftpClient_transferFileType=2 #是否重命名 ftpClient_renameUploaded=true #重新连接时间 ftpClient_retryTimes=1200 #缓存大小 ftpClient_bufferSize=1024 #默认进入的路径 ftpClient_workingDirectory=/home/ftpadmin/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

三、新建一个FTP客户端属性类

package com.eakom.common.util.ftpPool;
/**
 * FTP属性相关的配置
 * @author eakom
 * @date 2018年1月11日
 */
public class FTPConfig{ private String host; private int port; private String username; private String password; private boolean passiveMode; private String encoding; private int clientTimeout; private int threadNum; private int transferFileType; private boolean renameUploaded; private int retryTimes; private int bufferSize; private String workingDirectory; public String getWorkingDirectory() { return workingDirectory; } public void setWorkingDirectory(String workingDirectory) { this.workingDirectory = workingDirectory; } public int getBufferSize() { return bufferSize; } public void setBufferSize(int bufferSize) { this.bufferSize = bufferSize; } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean getPassiveMode() { return passiveMode; } public void setPassiveMode(boolean passiveMode) { this.passiveMode = passiveMode; } public String getEncoding() { return encoding; } public void setEncoding(String encoding) { this.encoding = encoding; } public int getClientTimeout() { return clientTimeout; } public void setClientTimeout(int clientTimeout) { this.clientTimeout = clientTimeout; } public int getThreadNum() { return threadNum; } public void setThreadNum(int threadNum) { this.threadNum = threadNum; } public int getTransferFileType() { return transferFileType; } public void setTransferFileType(int transferFileType) { this.transferFileType = transferFileType; } public boolean isRenameUploaded() { return renameUploaded; } public void setRenameUploaded(boolean renameUploaded) { this.renameUploaded = renameUploaded; } public int getRetryTimes() { return retryTimes; } public void setRetryTimes(int retryTimes) { this.retryTimes = retryTimes; } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103

类中的属性与配置文件ftpClient.properties中的属性相对应

四、新建一个FTP客户端工厂类,继承于commons-pool 包中的BasePooledObjectFactory类,并重写create()、 wrap(FTPClient ftpClient)、destroyObject(PooledObject p)和validateObject(PooledObject p)四个方法

package com.eakom.common.util.ftpPool;

import java.io.IOException;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.BasePooledObjectFactory; import org.apache.commons.pool2.PooledObject; import org.apache.commons.pool2.impl.DefaultPooledObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class FTPClientFactory extends BasePooledObjectFactory<FTPClient> { private static Logger logger = LoggerFactory.getLogger(FTPClientFactory.class); private FTPConfig ftpConfig; public FTPClientFactory(FTPConfig ftpConfig) { this.ftpConfig = ftpConfig; } /** * 新建对象 */ @Override public FTPClient create() throws Exception { FTPClient ftpClient = new FTPClient(); ftpClient.setConnectTimeout(ftpConfig.getClientTimeout()); try { ftpClient.connect(ftpConfig.getHost(), ftpConfig.getPort()); int reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); logger.error("FTPServer 拒绝连接"); return null; } boolean result = ftpClient.login(ftpConfig.getUsername(),ftpConfig.getPassword()); if (!result) { logger.error("ftpClient登陆失败!"); throw new Exception("ftpClient登陆失败! userName:"+ ftpConfig.getUsername() + " ; password:" + ftpConfig.getPassword()); } ftpClient.setFileType(ftpConfig.getTransferFileType()); ftpClient.setBufferSize(ftpConfig.getBufferSize()); ftpClient.setControlEncoding(ftpConfig.getEncoding()); if (ftpConfig.getPassiveMode()) { ftpClient.enterLocalPassiveMode(); } ftpClient.changeWorkingDirectory(ftpConfig.getWorkingDirectory()); } catch (IOException e) { logger.error("FTP连接失败:", e); } return ftpClient; } @Override public PooledObject<FTPClient> wrap(FTPClient ftpClient) { return new DefaultPooledObject<FTPClient>(ftpClient); } /** * 销毁对象 */ @Override public void destroyObject(PooledObject<FTPClient> p) throws Exception { FTPClient ftpClient = p.getObject(); ftpClient.logout(); super.destroyObject(p); } /** * 验证对象 */ @Override public boolean validateObject(PooledObject<FTPClient> p) { FTPClient ftpClient = p.getObject(); boolean connect = false; try { connect = ftpClient.sendNoOp(); if(connect){ ftpClient.changeWorkingDirectory(ftpConfig.getWorkingDirectory()); } } catch (IOException e) { e.printStackTrace(); } return connect; } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

五、新建FTP连接池类,连接池中有带有一个构造方法,连接器初始化时,自动新建commons-pool包中的GenericObjectPool类,初始化连接池;

package com.eakom.common.util.ftpPool; import java.io.InputStream; import java.util.Properties; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.pool2.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; public class FTPClientPool{ private GenericObjectPool<FTPClient> ftpClientPool; public FTPClientPool(InputStream in){ Properties pro = new Properties(); try { pro.load(in); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } // 初始化对象池配置 GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); poolConfig.setBlockWhenExhausted(Boolean.parseBoolean(pro.getProperty("ftpClient_blockWhenExhausted"))); poolConfig.setMaxWaitMillis(Long.parseLong(pro.getProperty("ftpClient_maxWait"))); poolConfig.setMinIdle(Integer.parseInt(pro.getProperty("ftpClient_minIdle"))); poolConfig.setMaxIdle(Integer.parseInt(pro.getProperty("ftpClient_maxIdle"))); poolConfig.setMaxTotal(Integer.parseInt(pro.getProperty("ftpClient_maxTotal"))); poolConfig.setTestOnBorrow(Boolean.parseBoolean(pro.getProperty("ftpClient_testOnBorrow"))); poolConfig.setTestOnReturn(Boolean.parseBoolean(pro.getProperty("ftpClient_testOnReturn"))); poolConfig.setTestOnCreate(Boolean.parseBoolean(pro.getProperty("ftpClient_testOnCreate"))); poolConfig.setTestWhileIdle(Boolean.parseBoolean(pro.getProperty("ftpClient_testWhileIdle"))); poolConfig.setLifo(Boolean.parseBoolean(pro.getProperty("ftpClient_lifo"))); FTPConfig ftpConfig=new FTPConfig(); ftpConfig.setHost(pro.getProperty("ftpClient_host")); ftpConfig.setPort(Integer.parseInt(pro.getProperty("ftpClient_port"))); ftpConfig.setUsername(pro.getProperty("ftpClient_username")); ftpConfig.setPassword(pro.getProperty("ftpClient_pasword")); ftpConfig.setClientTimeout(Integer.parseInt(pro.getProperty("ftpClient_clientTimeout"))); ftpConfig.setEncoding(pro.getProperty("ftpClient_encoding")); ftpConfig.setWorkingDirectory(pro.getProperty("ftpClient_workingDirectory")); ftpConfig.setPassiveMode(Boolean.parseBoolean(pro.getProperty("ftpClient_passiveMode"))); ftpConfig.setRenameUploaded(Boolean.parseBoolean(pro.getProperty("ftpClient_renameUploaded"))); ftpConfig.setRetryTimes(Integer.parseInt(pro.getProperty("ftpClient_retryTimes"))); ftpConfig.setTransferFileType(Integer.parseInt(pro.getProperty("ftpClient_transferFileType"))); ftpConfig.setBufferSize(Integer.parseInt(pro.getProperty("ftpClient_bufferSize"))); // 初始化对象池 ftpClientPool = new GenericObjectPool<FTPClient>(new FTPClientFactory(ftpConfig), poolConfig); } public FTPClient borrowObject() throws Exception { /* System.out.println("获取前"); System.out.println("活动"+ftpClientPool.getNumActive()); System.out.println("等待"+ftpClientPool.getNumWaiters()); System.out.println("----------");*/ return ftpClientPool.borrowObject(); } public void returnObject(FTPClient ftpClient) { /*System.out.println("归还前"); System.out.println("活动"+ftpClientPool.getNumActive()); System.out.println("等待"+ftpClientPool.getNumWaiters()); System.out.println("----------");*/ ftpClientPool.returnObject(ftpClient); System.out.println("归还后"); System.out.println("活动"+ftpClientPool.getNumActive()); System.out.println("等待"+ftpClientPool.getNumWaiters()); System.out.println("----------"); } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

六、测试连接池 
同时启动多个线程,观察连接池内,FTPClient的数量的变化

package com.eakom.common.util.ftpPool;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream; import java.util.Date; import org.apache.commons.net.ftp.FTPClient; public class Ftp { private static FTPClientPool ftpClientPool; static{ // ftpClientPool=new FTPClientPool(Thread.currentThread().getContextClassLoader().getResourceAsStream("ftpClient.properties")); ftpClientPool=new FTPClientPool(Ftp.class.getClassLoader().getResourceAsStream("ftpClient.properties")); } public static void main(String[] args) { for(int i=0;i<50;i++){ Thread thread=new Thread(new Runnable() { @Override public void run() { sendFile(); } }); thread.start(); try { thread.sleep(15); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void sendFile(){ long start = System.currentTimeMillis(); InputStream inputStream = null; FTPClient ftpClient = null; try { ftpClient = ftpClientPool.borrowObject(); } catch (Exception e) { e.printStackTrace(); } try { String path="C:/Users/Administrator/Desktop/44/中文.txt"; File file = new File(path); ftpClient.changeWorkingDirectory("/home/ftpadmin/aa"); inputStream = new FileInputStream(file); String fileName =new Date().getSeconds()+new Date().getSeconds()+".txt"; boolean flag = ftpClient.storeFile(new String(fileName.getBytes("GBK"), "iso-8859-1") , inputStream); long end = System.currentTimeMillis(); System.out.println("**********************************************"+flag); long lo=end-start; System.out.println("耗时:"+lo); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ ftpClientPool.returnObject(ftpClient); } } }

转载于:https://www.cnblogs.com/wq3435/p/9634974.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值