前言
最近在项目中需要和ftp服务器进行交互,在网上找了一下关于ftp上传下载的工具类,大致有两种。
第一种是单例模式的类。
第二种是另外定义一个Service,直接通过Service来实现ftp的上传下载。
这两种感觉都有利弊。
第一种实现了代码复用,但是配置信息全需要写在类中,维护比较复杂。
第二种如果是spring框架,可以通过propertis文件,动态的注入配置信息,但是又不能代码复用。
所以我打算自己实现一个工具类,来把上面的两种优点进行整合。顺便把一些上传过程中一些常见的问题也给解决了。
因为我使用的是spring框架,如果把工具类声明为bean给spring管理,他默认就是单例的,所以不需要我再实现单例。并且因为是bean,所以我可以把properties文件的属性注入bean的属性中,实现解耦,下面是具体代码:
?
|
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
|
package com.cky.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//使用spring自动生成单例对象,
//@Component
public class FtpUtil {
//通过properties文件自动注入
@Value("${ftp.host}")
private String host; //ftp服务器ip
@Value("${ftp.port}")
private int port; //ftp服务器端口
@Value("${ftp.username}")
private String username;//用户名
@Value("${ftp.password}")
private String password;//密码
@Value("${ftp.basePath}")
private String basePath;//存放文件的基本路径
//测试的时候把这个构造函数打开,设置你的初始值,然后在代码后面的main方法运行测试
/*public FtpUtil() {
//System.out.println(this.toString());
host="192.168.100.77";
port=21;
username="ftpuser";
password="ftp54321";
basePath="/home/ftpuser/";
}*/
/**
*
* @param path 上传文件存放在服务器的路径
* @param filename 上传文件名
* @param input 输入流
* @return
*/
public boolean fileUpload(String path,String filename,InputStream input) {
FTPClient ftp=new FTPClient();
try {
ftp.connect(host, port);
ftp.login(username, password);
//设置文件编码格式
ftp.setControlEncoding("UTF-8");
//ftp通信有两种模式
//PORT(主动模式)客户端开通一个新端口(>1024)并通过这个端口发送命令或传输数据,期间服务端只使用他开通的一个端口,例如21
//PASV(被动模式)客户端向服务端发送一个PASV命令,服务端开启一个新端口(>1024),并使用这个端口与客户端的21端口传输数据
//由于客户端不可控,防火墙等原因,所以需要由服务端开启端口,需要设置被动模式
ftp.enterLocalPassiveMode();
//设置传输方式为流方式
ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
//获取状态码,判断是否连接成功
if(!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
throw new RuntimeException("FTP服务器拒绝连接");
}
//转到上传文件的根目录
if(!ftp.changeWorkingDirectory(basePath)) {
throw new RuntimeException("根目录不存在,需要创建");
}
//判断是否存在目录
if(!ftp.changeWorkingDirectory(path)) {
String[] dirs=path.split("/");
//创建目录
for (String dir : dirs) {
if(null==dir||"".equals(dir)) continue;
//判断是否存在目录
if(!ftp.changeWorkingDirectory(dir)) {
//不存在则创建
if(!ftp.makeDirectory(dir)) {
throw new RuntimeException("子目录创建失败");
}
//进入新创建的目录
ftp.changeWorkingDirectory(dir);
}
}
//设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
//上传文件
if(!ftp.storeFile(filename, input)) {
return false;
}
input.close();
ftp.logout();
return true;
}
} catch (Exception e) {
throw new RuntimeException(e);
}finally {
if(ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
return false;
}
/**
*
* @param filename 文件名,注意!此处文件名为加路径文件名,如:/2015/06/04/aa.jpg
* @param localPath 存放到本地第地址
* @return
*/
public boolean downloadFile(String filename,String localPath) {
FTPClient ftp=new FTPClient();
try {
ftp.connect(host, port);
ftp.login(username, password);
//设置文件编码格式
ftp.setControlEncoding("UTF-8");
//ftp通信有两种模式
//PORT(主动模式)客户端开通一个新端口(>1024)并通过这个端口发送命令或传输数据,期间服务端只使用他开通的一个端口,例如21
//PASV(被动模式)客户端向服务端发送一个PASV命令,服务端开启一个新端口(>1024),并使用这个端口与客户端的21端口传输数据
//由于客户端不可控,防火墙等原因,所以需要由服务端开启端口,需要设置被动模式
ftp.enterLocalPassiveMode();
//设置传输方式为流方式
ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
//获取状态码,判断是否连接成功
if(!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
throw new RuntimeException("FTP服务器拒绝连接");
}
int index=filename.lastIndexOf("/");
//获取文件的路径
String path=filename.substring(0, index);
//获取文件名
String name=filename.substring(index+1);
//判断是否存在目录
if(!ftp.changeWorkingDirectory(basePath+path)) {
throw new RuntimeException("文件路径不存在:"+basePath+path);
}
//获取该目录所有文件
FTPFile[] files=ftp.listFiles();
for (FTPFile file : files) {
//判断是否有目标文件
//System.out.println("文件名"+file.getName()+"---"+name);
if(file.getName().equals(name)) {
//System.out.println("找到文件");
//如果找到,将目标文件复制到本地
File localFile =new File(localPath+"/"+file.getName());
OutputStream out=new FileOutputStream(localFile);
ftp.retrieveFile(file.getName(), out);
out.close();
}
}
ftp.logout();
return true;
} catch (Exception e) {
throw new RuntimeException(e);
}finally {
if(ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
//两个功能其中一个使用的话另一个需要注释
public static void main(String []args) {
//上传测试-----------------------------------
/*FileInputStream in;
try {
in=new FileInputStream(new File("C:\\\\Users\\\\Administrator\\\\Desktop\\\\json.png"));
FtpUtil ftputil=new FtpUtil();
boolean flag=ftputil.fileUpload("/2015/06/04", "aa.jpg", in);
System.out.println(flag);
}catch (Exception e) {
e.printStackTrace();
}finally {
}*/
//下载测试--------------------------------------
String filename="/2015/06/04/aa.jpg";
String localPath="F:\\\\";
FtpUtil ftputil=new FtpUtil();
ftputil.downloadFile(filename, localPath);
}
//get set方法自己添加
//..............
}
|
具体使用
第一步:配置spring加载properties文件
applicationContext.xml
?
|
1
2
3
4
5
6
7
|
<context:property-placeholder location="classpath:*.properties"/>
ftp.properties
ftp.host=192.168.100.77
ftp.port=21
ftp.username=ftpuser
ftp.password=ftp54321
ftp.basePath=/home/ftpuser/
|
第二步:将工具类声明为bean
xml方式
?
|
1
2
3
4
5
6
7
|
<bean id="ftpUtil" class="com.cky.util.FtpUtil">
<property name="host" value="${ftp.host}"></property>
<property name="port" value="${ftp.port}"></property>
<property name="username" value="${ftp.username}"></property>
<property name="password" value="${ftp.password}"></property>
<property name="basePath" value="${ftp.basePath}"></property>
</bean>
|
注解方式,组件扫描
?
|
1
|
<context:component-scan base-package="com.cky.util"></context:component-scan>
|
第三部:注入使用
?
|
1
2
|
@Autowired
private FtpUtil ftpUtil;
|
总结
以上所述是小编给大家介绍的Spring FTP上传下载工具类遇到问题小结,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对快网idc网站的支持!
原文链接:http://www.cnblogs.com/chenkeyu/p/8001624.html
相关文章
猜你喜欢
- 64M VPS建站:是否适合初学者操作和管理? 2025-06-10
- ASP.NET自助建站系统中的用户注册和登录功能定制方法 2025-06-10
- ASP.NET自助建站系统的域名绑定与解析教程 2025-06-10
- 个人服务器网站搭建:如何选择合适的服务器提供商? 2025-06-10
- ASP.NET自助建站系统中如何实现多语言支持? 2025-06-10
TA的动态
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
- 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
- 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
- 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
- 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
快网idc优惠网
QQ交流群
您的支持,是我们最大的动力!
热门文章
-
2025-06-04 39
-
2025-05-27 85
-
2025-05-25 38
-
2025-05-29 86
-
2025-06-04 57
热门评论

