国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - Spring Boot整合FTPClient線程池的實現示例

Spring Boot整合FTPClient線程池的實現示例

2021-06-24 09:59hrabbits Java教程

這篇文章主要介紹了Spring Boot整合FTPClient線程池的實現示例,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

最近在寫一個ftp上傳工具,用到了apache的ftpclient,但是每個線程頻繁的創建和銷毀ftpclient對象對服務器的壓力很大,因此,此處最好使用一個ftpclient連接池。仔細翻了一下apache的api,發現它并沒有一個ftpclientpool的實現,所以,不得不自己寫一個ftpclientpool。下面就大體介紹一下開發連接池的整個過程,供大家參考。

我們可以利用apache提供的common-pool包來協助我們開發連接池。而開發一個簡單的對象池,僅需要實現common-pool 包中的objectpool和poolableobjectfactory兩個接口即可。

線程池的意義

為了減少頻繁創建、銷毀對象帶來的性能消耗,我們可以利用對象池的技術來實現對象的復用。對象池提供了一種機制,它可以管理對象池中對象的生命周期,提供了獲取和釋放對象的方法,可以讓客戶端很方便的使用對象池中的對象。

pom引入依賴

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- ftpclient依賴包-->
   <dependency>
     <groupid>commons-net</groupid>
     <artifactid>commons-net</artifactid>
     <version>3.5</version>
   </dependency>
 
   <!-- 線程池-->
   <dependency>
     <groupid>commons-pool</groupid>
     <artifactid>commons-pool</artifactid>
     <version>1.6</version>
   </dependency>
 
   <dependency>
     <groupid>org.apache.commons</groupid>
     <artifactid>commons-pool2</artifactid>
     <version>2.0</version>
   </dependency>

創建ftp配置信息

在resources目錄下創建ftp.properties配置文件,目錄結構如下:

Spring Boot整合FTPClient線程池的實現示例

添加如下的配置信息:

?
1
2
3
4
5
6
7
8
9
10
########### ftp用戶名稱 ###########
ftp.username=hrabbit
########### ftp用戶密碼 ###########
ftp.password=123456
########### ftp主機ip ###########
ftp.host=127.0.0.1
########### ftp主機端口號 ###########
ftp.port=21
########### 保存根路徑 ###########
ftp.baseurl=/

創建ftpproperties.java配置文件

加載配置內容到spring中,配置信息基本延用我的就可以。

?
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
/**
 * ftp的配置信息
 * @auther: hrabbit
 * @date: 2018-12-03 2:06 pm
 * @description:
 */
@data
@component
@propertysource("classpath:ftp.properties")
@configurationproperties(prefix = "ftp")
public class ftpproperties {
 
  private string username;
 
  private string password;
 
  private string host;
 
  private integer port;
 
  private string baseurl;
 
  private integer passivemode = ftp.binary_file_type;
 
  private string encoding="utf-8";
 
  private int clienttimeout=120000;
 
  private int buffersize;
 
  private int transferfiletype=ftp.binary_file_type;
 
  private boolean renameuploaded;
 
  private int retrytime;
}

創建ftpclientpool線程池

?
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
 * 自定義實現ftp連接池
 * @auther: hrabbit
 * @date: 2018-12-03 3:40 pm
 * @description:
 */
@slf4j
@suppresswarnings("all")
public class ftpclientpool implements objectpool<ftpclient> {
 
  private static final int default_pool_size = 10;
 
  public blockingqueue<ftpclient> blockingqueue;
 
  private ftpclientfactory factory;
 
  public ftpclientpool(ftpclientfactory factory) throws exception {
    this(default_pool_size, factory);
  }
 
  public ftpclientpool(int poolsize, ftpclientfactory factory) throws exception {
    this.factory = factory;
    this.blockingqueue = new arrayblockingqueue<ftpclient>(poolsize);
    initpool(poolsize);
  }
 
  /**
   * 初始化連接池
   * @param maxpoolsize
   *         最大連接數
   * @throws exception
   */
  private void initpool(int maxpoolsize) throws exception {
    int count = 0;
    while(count < maxpoolsize) {
      this.addobject();
      count++;
    }
  }
 
  /**
   * 從連接池中獲取對象
   */
  @override
  public ftpclient borrowobject() throws exception {
    ftpclient client = blockingqueue.take();
    if(client == null) {
      client = factory.makeobject();
    } else if(!factory.validateobject(client)) {
      invalidateobject(client);
      client = factory.makeobject();
    }
    return client;
  }
 
  /**
   * 返還一個對象(鏈接)
   */
  @override
  public void returnobject(ftpclient client) throws exception {
    if ((client != null) && !blockingqueue.offer(client,2,timeunit.minutes)) {
      try {
        factory.destroyobject(client);
      } catch (exception e) {
        throw e;
      }
    }
  }
 
  /**
   * 移除無效的對象(ftp客戶端)
   */
  @override
  public void invalidateobject(ftpclient client) throws exception {
    blockingqueue.remove(client);
  }
 
  /**
   * 增加一個新的鏈接,超時失效
   */
  @override
  public void addobject() throws exception {
    blockingqueue.offer(factory.makeobject(), 2, timeunit.minutes);
  }
 
  /**
   * 重新連接
   */
  public ftpclient reconnect() throws exception {
    return factory.makeobject();
  }
 
  /**
   * 獲取空閑鏈接數(這里暫不實現)
   */
  @override
  public int getnumidle() {
    return blockingqueue.size();
  }
 
  /**
   * 獲取正在被使用的鏈接數
   */
  @override
  public int getnumactive() {
    return default_pool_size - getnumidle();
  }
 
  @override
  public void clear() throws exception {
 
  }
 
  /**
   * 關閉連接池
   */
  @override
  public void close() {
    try {
      while(blockingqueue.iterator().hasnext()) {
        ftpclient client = blockingqueue.take();
        factory.destroyobject(client);
      }
    } catch(exception e) {
      log.error("close ftp client pool failed...{}", e);
    }
  }
 
  /**
   * 增加一個新的鏈接,超時失效
   */
  public void addobject(ftpclient ftpclient) throws exception {
    blockingqueue.put(ftpclient);
  }
}

創建一個ftpclientfactory工廠類

創建ftpclientfactory實現poolableobjectfactory的接口,ftpclient工廠類,通過ftpclient工廠提供ftpclient實例的創建和銷毀

?
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
/**
 * ftpclient 工廠
 * @auther: hrabbit
 * @date: 2018-12-03 3:41 pm
 * @description:
 */
@slf4j
@suppresswarnings("all")
public class ftpclientfactory implements poolableobjectfactory<ftpclient> {
 
  private ftpproperties ftpproperties;
 
  public ftpclientfactory(ftpproperties ftpproperties) {
    this.ftpproperties = ftpproperties;
  }
 
  @override
  public ftpclient makeobject() throws exception {
    ftpclient ftpclient = new ftpclient();
    ftpclient.setcontrolencoding(ftpproperties.getencoding());
    ftpclient.setconnecttimeout(ftpproperties.getclienttimeout());
    try {
      ftpclient.connect(ftpproperties.gethost(), ftpproperties.getport());
      int reply = ftpclient.getreplycode();
      if (!ftpreply.ispositivecompletion(reply)) {
        ftpclient.disconnect();
        log.warn("ftpserver refused connection");
        return null;
      }
      boolean result = ftpclient.login(ftpproperties.getusername(), ftpproperties.getpassword());
      ftpclient.setfiletype(ftpproperties.gettransferfiletype());
      if (!result) {
        log.warn("ftpclient login failed... username is {}", ftpproperties.getusername());
      }
    } catch (exception e) {
      log.error("create ftp connection failed...{}", e);
      throw e;
    }
 
    return ftpclient;
  }
 
  @override
  public void destroyobject(ftpclient ftpclient) throws exception {
    try {
      if(ftpclient != null && ftpclient.isconnected()) {
        ftpclient.logout();
      }
    } catch (exception e) {
      log.error("ftp client logout failed...{}", e);
      throw e;
    } finally {
      if(ftpclient != null) {
        ftpclient.disconnect();
      }
    }
 
  }
 
  @override
  public boolean validateobject(ftpclient ftpclient) {
    try {
      return ftpclient.sendnoop();
    } catch (exception e) {
      log.error("failed to validate client: {}");
    }
    return false;
  }
 
  @override
  public void activateobject(ftpclient obj) throws exception {
    //do nothing
 
  }
 
  @override
  public void passivateobject(ftpclient obj) throws exception {
    //do nothing
 
  }
}

創建ftputils.java的工具類

ftputils.java中封裝了上傳、下載等方法,在項目啟動的時候,在@postconstruct注解的作用下通過執行init()的方法,創建ftpclientfactory工廠中,并初始化了ftpclientpool線程池,這樣每次調用方法的時候,都直接從ftpclientpool中取出一個ftpclient對象

?
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
/**
 * @auther: hrabbit
 * @date: 2018-12-03 3:47 pm
 * @description:
 */
@slf4j
@component
public class ftputils {
 
  /**
   * ftp的連接池
   */
  @autowired
  public static ftpclientpool ftpclientpool;
  /**
   * ftpclient對象
   */
  public static ftpclient ftpclient;
 
 
  private static ftputils ftputils;
 
  @autowired
  private ftpproperties ftpproperties;
 
  /**
   * 初始化設置
   * @return
   */
  @postconstruct
  public boolean init() {
    ftpclientfactory factory = new ftpclientfactory(ftpproperties);
    ftputils = this;
    try {
      ftpclientpool = new ftpclientpool(factory);
    } catch (exception e) {
      e.printstacktrace();
      return false;
    }
    return true;
  }
 
 
  /**
   * 獲取連接對象
   * @return
   * @throws exception
   */
  public static ftpclient getftpclient() throws exception {
    //初始化的時候從隊列中取出一個連接
    if (ftpclient==null) {
      synchronized (ftpclientpool) {
        ftpclient = ftpclientpool.borrowobject();
      }
    }
    return ftpclient;
  }
 
 
  /**
   * 當前命令執行完成命令完成
   * @throws ioexception
   */
  public void complete() throws ioexception {
    ftpclient.completependingcommand();
  }
 
  /**
   * 當前線程任務處理完成,加入到隊列的最后
   * @return
   */
  public void disconnect() throws exception {
    ftpclientpool.addobject(ftpclient);
  }
 
  /**
   * description: 向ftp服務器上傳文件
   *
   * @version1.0
   * @param remotefile
   *      上傳到ftp服務器上的文件名
   * @param input
   *      本地文件流
   * @return 成功返回true,否則返回false
   */
  public static boolean uploadfile(string remotefile, inputstream input) {
    boolean result = false;
    try {
      getftpclient();
      ftpclient.enterlocalpassivemode();
      result = ftpclient.storefile(remotefile, input);
      input.close();
      ftpclient.disconnect();
    } catch (exception e) {
      e.printstacktrace();
    }
    return result;
  }
 
  /**
   * description: 向ftp服務器上傳文件
   *
   * @version1.0
   * @param remotefile
   *      上傳到ftp服務器上的文件名
   * @param localfile
   *      本地文件
   * @return 成功返回true,否則返回false
   */
  public static boolean uploadfile(string remotefile, string localfile){
    fileinputstream input = null;
    try {
      input = new fileinputstream(new file(localfile));
    } catch (filenotfoundexception e) {
      e.printstacktrace();
    }
    return uploadfile(remotefile, input);
  }
 
  /**
   * 拷貝文件
   * @param fromfile
   * @param tofile
   * @return
   * @throws exception
   */
  public boolean copyfile(string fromfile, string tofile) throws exception {
    inputstream in=getfileinputstream(fromfile);
    getftpclient();
    boolean flag = ftpclient.storefile(tofile, in);
    in.close();
    return flag;
  }
 
  /**
   * 獲取文件輸入流
   * @param filename
   * @return
   * @throws ioexception
   */
  public static inputstream getfileinputstream(string filename) throws exception {
    bytearrayoutputstream fos=new bytearrayoutputstream();
    getftpclient();
    ftpclient.retrievefile(filename, fos);
    bytearrayinputstream in=new bytearrayinputstream(fos.tobytearray());
    fos.close();
    return in;
  }
 
  /**
   * description: 從ftp服務器下載文件
   *
   * @version1.0
   * @return
   */
  public static boolean downfile(string remotefile, string localfile){
    boolean result = false;
    try {
      getftpclient();
      outputstream os = new fileoutputstream(localfile);
      ftpclient.retrievefile(remotefile, os);
      ftpclient.logout();
      ftpclient.disconnect();
      result = true;
    } catch (exception e) {
      e.printstacktrace();
    } finally {
      try {
      } catch (exception e) {
        e.printstacktrace();
      }
    }
    return result;
  }
 
  /**
   * 從ftp中獲取文件流
   * @param filepath
   * @return
   * @throws exception
   */
  public static inputstream getinputstream(string filepath) throws exception {
    getftpclient();
    inputstream inputstream = ftpclient.retrievefilestream(filepath);
    return inputstream;
  }
 
  /**
   * ftp中文件重命名
   * @param fromfile
   * @param tofile
   * @return
   * @throws exception
   */
  public boolean rename(string fromfile,string tofile) throws exception {
    getftpclient();
    boolean result = ftpclient.rename(fromfile,tofile);
    return result;
  }
 
  /**
   * 獲取ftp目錄下的所有文件
   * @param dir
   * @return
   */
  public ftpfile[] getfiles(string dir) throws exception {
    getftpclient();
    ftpfile[] files = new ftpfile[0];
    try {
      files = ftpclient.listfiles(dir);
    }catch (throwable thr){
      thr.printstacktrace();
    }
    return files;
  }
 
  /**
   * 獲取ftp目錄下的某種類型的文件
   * @param dir
   * @param filter
   * @return
   */
  public ftpfile[] getfiles(string dir, ftpfilefilter filter) throws exception {
    getftpclient();
    ftpfile[] files = new ftpfile[0];
    try {
      files = ftpclient.listfiles(dir, filter);
    }catch (throwable thr){
      thr.printstacktrace();
    }
    return files;
  }
 
  /**
   * 創建文件夾
   * @param remotedir
   * @return 如果已經有這個文件夾返回false
   */
  public boolean makedirectory(string remotedir) throws exception {
    getftpclient();
    boolean result = false;
    try {
      result = ftpclient.makedirectory(remotedir);
    } catch (ioexception e) {
      e.printstacktrace();
    }
    return result;
  }
 
  public boolean mkdirs(string dir) throws exception {
    boolean result = false;
    if (null == dir) {
      return result;
    }
    getftpclient();
    ftpclient.changeworkingdirectory("/");
    stringtokenizer dirs = new stringtokenizer(dir, "/");
    string temp = null;
    while (dirs.hasmoreelements()) {
      temp = dirs.nextelement().tostring();
      //創建目錄
      ftpclient.makedirectory(temp);
      //進入目錄
      ftpclient.changeworkingdirectory(temp);
      result = true;
    }
    ftpclient.changeworkingdirectory("/");
    return result;
  }
}

創建ftpclienttest.java測試類

上傳一張圖片到ftp服務器,并將文件重新命名為hrabbit.jpg,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * ftpclient測試
 * @auther: hrabbit
 * @date: 2018-12-21 9:14 pm
 * @description:
 */
@runwith(springrunner.class)
@springboottest
public class ftpclienttest {
 
  /**
   * 測試上傳
   */
  @test
  public void uploadfile(){
    boolean flag = ftputils.uploadfile("hrabbit.jpg", "/users/mrotaku/downloads/klklklkl_4x.jpg");
    assert.assertequals(true, flag);
  }
 
}

程序完美運行,這時候我們查看我們的ftp服務器,http://localhost:8866/hrabbit.jpg

Spring Boot整合FTPClient線程池的實現示例

碼云地址:https://gitee.com/hrabbit/hrabbit-admin

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://www.jianshu.com/p/6270b2308c4e

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日韩 欧美 精品 | 久久亚洲一区二区 | 云南一级毛片 | 精品久久97| 久久一区| 国产精品一码二码三码在线 | 99热69| 欧美专区在线观看 | 51ⅴ精品国产91久久久久久 | 亚洲精品乱码8久久久久久日本 | 亚洲国产精品一区二区久久 | 亚洲免费网 | 日韩在线不卡 | 国产性猛交xxxx免费看久久 | 欧美在线观看一区二区 | 特级毛片在线大全免费播放 | 亚洲自拍中文 | 一区二区三区 在线 | 大胆一区 | 久久久久久一区二区三区 | 北条麻妃在线一区二区免费播放 | 欧洲精品码一区二区三区免费看 | 成人免费在线视频播放 | 一区二区av在线 | 欧洲成人午夜免费大片 | 亚洲精品久久久久久下一站 | 午夜寂寞少妇aaa片毛片 | 亚洲免费视频网 | 成人精品一区二区三区 | 亚洲一区二区三区免费视频 | 欧美成人精品一区二区三区在线看 | 精品在线二区 | 欧美在线免费 | 国产综合精品一区二区三区 | 中文字幕日韩欧美一区二区三区 | 欧美久久免费 | 欧美福利在线 | 在线播放亚洲 | 黄视频免费 | 亚洲一区在线日韩在线深爱 | 中文字幕日韩欧美一区二区三区 |