转自: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); } } }