简单实现ftp递归下载,直接上代码。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
220package cn.com.egova.easyshare.common.utils;
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.apache.log4j.Logger;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.SocketException;
/**
* 使用apache的commons-net下载ftp文件或者文件夹到本地
* 一定要注意中文路径或者哟中文的文件,在执行ftp命令的时候要转换FTP协议的规定编码
* Created by gxf on 17-6-12.
*/
public class FtpUtil {
private String username;
private String password;
private String ftpHostName;
private int port = 21;
private FTPClient ftpClient = new FTPClient();
private final Logger logger = Logger.getLogger(FtpUtil.class);
private static FtpUtil instance;
/**
* 本地字符编码
*/
private static String LOCAL_CHARSET = "GBK";
// FTP协议里面,规定文件名编码为iso-8859-1
private static String SERVER_CHARSET = "ISO-8859-1";
public static FtpUtil getInstance(String username, String password, String ftpHostName, int port) {
if (instance == null)
instance = new FtpUtil(username, password, ftpHostName, port);
return instance;
}
public FtpUtil(String username, String password,
String ftpHostName, int port) {
this.username = username;
this.password = password;
this.ftpHostName = ftpHostName;
this.port = port;
}
/**
* 建立连接,设置各种连接属性
*/
public void connect() {
try {
logger.debug("开始连接");
// 连接
ftpClient.connect(ftpHostName, port);
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
}
// 登录
ftpClient.login(username, password);
ftpClient.setBufferSize(1024 * 1024);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
//本地文件名编码
ftpClient.setControlEncoding(LOCAL_CHARSET);
logger.debug("登录成功!");
} catch (SocketException e) {
logger.error("", e);
} catch (IOException e) {
logger.error("", e);
}
}
/**
* 关闭输入输出流
*/
public void close() {
try {
ftpClient.logout();
logger.info("退出登录");
ftpClient.disconnect();
logger.info("关闭连接");
} catch (IOException e) {
logger.error("", e);
}
}
/**
* @param ftpFileName ftp服务器上的文件或者路径
* @param localDir 本地保存的文件或者路径
* @throws Exception
*/
public void downFileOrDir(String ftpFileName, String localDir, boolean isDir) throws Exception {
//本地输出流记得手动关闭,系统调用不会关闭本地流
FileOutputStream fos = null;
try {
boolean downloadSuccess = false;
File temp = new File(localDir);
if (!temp.exists() && isDir) {
temp.mkdirs();
}
// 判断是否是目录
if (isDir) {
//切换到当前目录
if (!ftpClient.changeWorkingDirectory(
new String(ftpFileName.getBytes(LOCAL_CHARSET), SERVER_CHARSET))) {
logger.debug("目录:" + ftpFileName + " 切换失败," + ftpClient.getReplyString());
return;
} else {
logger.debug("目录:" + ftpFileName + " 切换成功," + ftpClient.getReplyString());
}
FTPFile[] ftpFile = ftpClient.listFiles();
for (int i = 0; i < ftpFile.length; i++) {
String fileName = ftpFile[i].getName();
//两个隐藏目录忽略
if (".".equals(fileName) || "..".equals(fileName))
continue;
if (ftpFileName.endsWith("/"))
ftpFileName = ftpFileName.substring(0, ftpFileName.length() - 1);
if (localDir.endsWith(File.separator))
localDir = localDir.substring(0, localDir.length() - 1);
//递归
downFileOrDir(ftpFileName + "/" + fileName, localDir
+ File.separator + fileName, ftpFile[i].isDirectory() ? true : false);
}
} else {
File localfile = new File(localDir);
String remoteFileName = new String(ftpFileName.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
if (!localfile.exists()) {
fos = new FileOutputStream(localfile);
downloadSuccess = ftpClient.retrieveFile(remoteFileName, fos);
} else {
logger.debug("开始删除本地文件:" + localfile);
localfile.delete();
logger.debug("文件已经删除");
fos = new FileOutputStream(localfile);
downloadSuccess = ftpClient.retrieveFile(remoteFileName, fos);
}
if (!downloadSuccess)
logger.debug(localfile.getCanonicalPath() + " 下载失败,返回代码:" + ftpClient.getReplyString());
else
logger.debug(localfile.getCanonicalPath() + " 下载成功,返回代码:" + ftpClient.getReplyString());
}
} catch (Exception e) {
logger.error("下载失败!", e);
throw e;
} finally {
if (fos != null) {
fos.close();
}
}
}
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 String getFtpHostName() {
return ftpHostName;
}
public void setFtpHostName(String ftpHostName) {
this.ftpHostName = ftpHostName;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public static void main(String[] args) throws Exception {
FtpUtil ftpUtil = FtpUtil.getInstance("administrator", "eland_2014", "192.168.177.12", 21);
ftpUtil.connect();
String filePath = "/coredatabase/575A651B5B424200B160F92854DE986A/12220165325039161771642/";
String localPath = filePath.replace("/",File.separator);
ftpUtil.downFileOrDir(filePath, "D:\\test" + localPath, true);
filePath = "/coredatabase/7917FCF268BE4CE09DD1C0154F9A3B0B/12920165325039689107501/";
localPath = filePath.replace("/",File.separator);
ftpUtil.downFileOrDir(filePath, "D:\\test" + localPath, true);
filePath = "/coredatabase/D1DEDCA33DDF47E6BA0FD697245C5D14/12320155325006100699716/";
localPath = filePath.replace("/",File.separator);
ftpUtil.downFileOrDir(filePath, "D:\\test" + localPath, true);
filePath = "/coredatabase/3AA5084212284DCEB358F57F33BBE71D/13020165325036258525268/";
localPath = filePath.replace("/",File.separator);
ftpUtil.downFileOrDir(filePath, "D:\\test" + localPath, true);
ftpUtil.close();
}
}
代码会递归下载传入的目录下的文件,并在本地生成ftp服务器同样的的目录结构,中文路径和文件需要对中文进行编码转换,代码中服务器中文编码是GBK的。