需先引用Apache的“commons-net-3.3.jar”

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
package com.xxxx.utils;  

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

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.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UploadUtil {

//////////////////////////////////////////// ftp//////////////////////////////////////

private static Logger logger = LoggerFactory.getLogger(UploadUtil.class);

private static FtpUser user = new FtpUser();// 默认用户,从配置文件读取

/**
* Description: 向FTP服务器上传文件(使用系统默认用户配置登录) ps:需保证该登录用户对指定的basePath有新建文件夹权限
* <br>
*
* @author ran.chunlin
* @date 2017年4月15日 下午3:46:30
* @param remoteSubPath
* FTP服务器文件存放路径。例如分日期存放:/2015/01/01
* @param remoteFileName
* 上传到FTP服务器上的文件名,含如.jpg的后缀
* @param randomSuffix
* 文件随机后缀名,一般使用时间戳(如果传null,将默认使用当前时间戳)
* @param input
* @return 上传的服务器文件全路径
* @throws FileNotFoundException
* @version 1.0
*/
public static String uploadFile(String remoteSubPath, String remoteFileName, String randomSuffix, InputStream input)
throws FileNotFoundException {

return uploadFile(user, remoteSubPath, remoteFileName, randomSuffix, input);
}

/**
* Description: 向FTP服务器上传文件 eq:需保证该登录用户对指定的basePath有新建文件夹权限 <br>
*
* @author ran.chunlin
* @date 2017年4月15日 上午10:53:28
* @param user
* @param remoteSubPath
* FTP服务器文件存放路径。例如分日期存放:/2015/01/01
* @param remoteFileName
* 上传到FTP服务器上的文件名,含如.jpg的后缀
* @param randomSuffix
* 文件随机后缀名,一般使用时间戳(如果传null,将默认使用当前时间戳)
* @param input
* 上传文件流
* @return 上传的服务器文件全路径
* @throws FileNotFoundException
* @version 1.0
*/
public static String uploadFile(FtpUser user, String remoteSubPath, String remoteFileName, String randomSuffix,
InputStream input) throws FileNotFoundException {

String result = null;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(user.getHost(), user.getPort());// 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(user.getUserName(), user.getPassWord());// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
// 切换到上传目录
if (!ftp.changeWorkingDirectory(user.getRemoteBasePath() + remoteSubPath)) {
// 如果目录不存在,创建目录
String[] dirs = remoteSubPath.split("/");
String tempPath = user.getRemoteBasePath();
for (String dir : dirs) {
if (null == dir || "".equals(dir))
continue;
tempPath += "/" + dir;
if (!ftp.changeWorkingDirectory(tempPath)) {
if (!ftp.makeDirectory(tempPath)) {
return result;
} else {
ftp.changeWorkingDirectory(tempPath);
}
}
}
}
// 设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
// 设置被动模式,默认为主动模式
ftp.enterLocalPassiveMode();
// 上传文件
String newName;
if (randomSuffix == null)
newName = remoteFileName + DateTime.now().toString("yyyyMMddHHmmssSSS"); // 重命名该文件,以配合前端的缓存策略
else
newName = remoteFileName + randomSuffix;
if (!ftp.storeFile(newName, input))
return result;

input.close();
ftp.logout();
result = user.getHost() + "/" + "images/" + remoteSubPath + "/" + newName;
logger.info("图片上传路径:" + result);
} catch (IOException e) {
logger.error("文件上传失败", e);
return null;
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
logger.error("ftp关闭失败", ioe);
return null;
}
}
}
return result;
}

/**
* Description: 从FTP服务器下载文件 <br>
*
* @author ran.chunlin
* @date 2017年4月15日 上午10:53:41
* @param user
* @param remotePath
* FTP服务器文件存放路径
* @param remoteFileName
* FTP服务器上的文件名
* @param localFilePath
* 本地存放路径
* @return
* @throws FileNotFoundException
* @version 1.0
*/
public static boolean downloadFile(FtpUser user, String remotePath, String remoteFileName, String localFilePath)
throws FileNotFoundException {
boolean result = false;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(user.getHost(), user.getPort());
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(user.getUserName(), user.getPassWord());// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
ftp.enterLocalPassiveMode();
FTPFile[] fs = ftp.listFiles();
for (FTPFile ff : fs) {
if (ff.getName().equals(remoteFileName)) {
File localFile = new File(localFilePath + "/" + ff.getName());

OutputStream is = new FileOutputStream(localFile);
ftp.retrieveFile(ff.getName(), is);
is.close();
}
}

ftp.logout();
result = true;
} catch (IOException e) {
logger.error("文件下载失败", e);
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return result;
}

}

/**
* ftp配置类
*
* @author ran.chunlin
* @version 1.0
*/
class FtpUser {

private static PropertyUtil propU = new PropertyUtil("remote/ftp.properties");

private String host = propU.getValue("ftp.host");// FTP服务器hostname
private int port = propU.getInt("ftp.port");// FTP服务器端口
private String userName = propU.getValue("ftp.name");// FTP登录账号
private String passWord = propU.getValue("ftp.pass");// FTP登录密码
// #对应Nginx配置映射为host/imgages/,注意,此处修改后,应修改对应的Nginx.conf文件
private String remoteBasePath = propU.getValue("ftp.remoteBasePath");// FTP服务器基础目录

public final static String IMG_ALLOW_SUFFIXS = propU.getValue("ftp.imgAllowSuffixs");// 图片允许的后缀名

public FtpUser() {
}

public FtpUser(String host, int port, String userName, String passWord, String remoteBasePath) {
this.host = host;
this.port = port;
this.userName = userName;
this.passWord = passWord;
this.remoteBasePath = remoteBasePath;
}

public String getHost() {
return host;
}

public int getPort() {
return port;
}

public String getUserName() {
return userName;
}

public String getPassWord() {
return passWord;
}

public String getRemoteBasePath() {
return remoteBasePath;
}

}