- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章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配置文件,目录结构如下:
添加如下的配置信息
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 。
码云地址:https://gitee.com/hrabbit/hrabbit-admin 。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://www.jianshu.com/p/6270b2308c4e 。
最后此篇关于Spring Boot整合FTPClient线程池的实现示例的文章就讲到这里了,如果你想了解更多关于Spring Boot整合FTPClient线程池的实现示例的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Sample data for IPv6? 除了 wireshark 在其网站上提供的内容之外,是否有可以下
我正在寻找可以集成到现有应用程序中并使用多拖放功能的示例或任何现成的解决方案。我在互联网上找到的大多数解决方案在将多个项目从 ListBox 等控件拖放到另一个 ListBox 时效果不佳。谁能指出我
我是 GATE Embedded 的新手,我尝试了简单的示例并得到了 NoClassDefFoundError。首先我会解释我尝试了什么 在 D:\project\gate-7.0 中下载并提取 Ga
是否有像 Eclipse 中的 SWT 示例那样的多合一 JFace 控件示例?搜索(在 stackoverflow.com 上使用谷歌搜索和搜索)对我没有帮助。 如果它是一个独立的应用程序或 ecl
我找不到任何可以清楚地解释如何通过 .net API(特别是 c#)使用谷歌计算引擎的内容。有没有人可以指点我什么? 附言我知道 API 引用 ( https://developers.google.
最近在做公司的一个项目时,客户需要我们定时获取他们矩阵系统的数据。在与客户进行对接时,提到他们的接口使用的目前不常用的BASIC 认证。天呢,它好不安全,容易被不法人监听,咋还在使用呀。但是没办法呀,
最近在做公司的一个项目时,客户需要我们定时获取他们矩阵系统的数据。在与客户进行对接时,提到他们的接口使用的目前不常用的BASIC 认证。天呢,它好不安全,容易被不法人监听,咋还在使用呀。但是没办法呀,
我正在尝试为我的应用程序设计配置文件格式并选择了 YAML。但是,这(显然)意味着我需要能够定义、解析和验证正确的 YAML 语法! 在配置文件中,必须有一个名为 widgets 的集合/序列。 .这
你能给我一个使用 pysmb 库连接到一些 samba 服务器的例子吗?我读过有类 smb.SMBConnection.SMBConnection(用户名、密码、my_name、remote_name
linux服务器默认通过22端口用ssh协议登录,这种不安全。今天想做限制,即允许部分来源ip连接服务器。 案例目标:通过iptables规则限制对linux服务器的登录。 处理方法:编
我一直在寻找任何 PostProjectAnalysisTask 工作代码示例,但没有看。 This页面指出 HipChat plugin使用这个钩子(Hook),但在我看来它仍然使用遗留的 Po
我发现了 GWT 的 CustomScrollPanel 以及如何自定义滚动条,但我找不到任何示例或如何设置它。是否有任何示例显示正在使用的自定义滚动条? 最佳答案 这是自定义 native 滚动条的
我正在尝试开发一个 Backbone Marionette 应用程序,我需要知道如何以最佳方式执行 CRUD(创建、读取、更新和销毁)操作。我找不到任何解释这一点的资源(仅适用于 Backbone)。
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题?通过 editing this post 添加详细信息并澄清问题. 去年关闭。 Improve this
我需要一个提交多个单独请求的 django 表单,如果没有大量定制,我找不到如何做到这一点的示例。即,假设有一个汽车维修店使用的表格。该表格将列出商店能够进行的所有可能的维修,并且用户将选择他们想要进
我有一个 Multi-Tenancy 应用程序。然而,这个相同的应用程序有 liquibase。我需要在我的所有数据源中运行 liquibase,但是我不能使用这个 Bean。 我的应用程序.yml
我了解有关单元测试的一般思想,并已在系统中发生复杂交互的场景中使用它,但我仍然对所有这些原则结合在一起有疑问。 我们被警告不要测试框架或数据库。好的 UI 设计不适合非人工测试。 MVC 框架不包括一
我正在使用 docjure并且它的 select-columns 函数需要一个列映射。我想获取所有列而无需手动指定。 如何将以下内容生成为惰性无限向量序列 [:A :B :C :D :E ... :A
$condition使用说明和 $param在 findByAttributes在 Yii 在大多数情况下,这就是我使用 findByAttributes 的方式 Person::model()->f
我在 Ubuntu 11.10 上安装了 qtcreator sudo apt-get install qtcreator 安装的版本有:QT Creator 2.2.1、QT 4.7.3 当我启动
我是一名优秀的程序员,十分优秀!