天天看點

java ftpclient 池_Java 自定義FTP連接配接池

一、引入FTP包和連接配接池包

commons-net

commons-net

3.5

org.apache.commons

commons-pool2

2.5.0

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;

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 {

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 wrap(FTPClient ftpClient) {

return new DefaultPooledObject(ftpClient);

}

@Override

public void destroyObject(PooledObject p) throws Exception {

FTPClient ftpClient = p.getObject();

ftpClient.logout();

super.destroyObject(p);

}

@Override

public boolean validateObject(PooledObject 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 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(new FTPClientFactory(ftpConfig), poolConfig);

}

public FTPClient borrowObject() throws Exception {

return ftpClientPool.borrowObject();

}

public void returnObject(FTPClient ftpClient) {

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);

}

}

}