0%

FTP Java Client

使用Apache Commons Net,从FTP服务器上下载文件。

需要使用的依赖:

1
2
3
4
5
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>

有几点需要注意的:

设置编码需要在connect之前。
设置ftp模式需要在connect之后。

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
package gy.finolo;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class FTPUtils {

private static Logger log = LoggerFactory.getLogger(FTPUtils.class);

public static FTPClient loginFTP(String hostname, int port, String username, String password) throws IOException {

FTPClient ftpClient = new FTPClient();
// 中文文件读取支持, 必须在connect之前设置
ftpClient.setControlEncoding("UTF-8");

ftpClient.connect(hostname, port);
// 被动模式设置, 必须在connect之后
ftpClient.enterLocalPassiveMode();

ftpClient.login(username, password);
// 设置文件类型为二进制, 若不设置, 压缩文件可能失败
// ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
log.info("ftp connection succeed");
} else {
String message = "ftp server connection error: " + ftpClient.getReplyString();
log.error(message);
throw new IOException(message);
}

return ftpClient;
}

public static void downloadFromFTP(FTPClient ftpClient, String ftpFile, String outDir) throws IOException {
// 在这个方法里把该转的路径都转为Path
boolean isDirectory = ftpClient.changeWorkingDirectory(ftpFile);
Path outDirPath = Paths.get(outDir);
if (isDirectory) {
downloadFTPDirectory2Directory(ftpClient, ftpFile, outDirPath);
} else {
downloadFTPFile2Directory(ftpClient, ftpFile, outDirPath);
}
}

// downlaod directory from ftp to directory (outDir)
private static void downloadFTPDirectory2Directory(FTPClient ftpClient, String ftpFileDir, Path outDirPath) throws IOException {
// 保证输出文件夹要存在
if (!Files.exists(outDirPath)) {
Files.createDirectories(outDirPath);
}

FTPFile[] ftpFiles = ftpClient.listFiles(ftpFileDir);
for (FTPFile file: ftpFiles) {
if (file.isFile()) {
// ftp file full path
Path ftpFileFullPath = Paths.get(ftpFileDir).resolve(file.getName());
downloadFTPFile2Directory(ftpClient, ftpFileFullPath.toString(), outDirPath);
// download files under the directory to the outDir
} else {
String dirName = file.getName();
Path subOutDirPath = outDirPath.resolve(dirName);
Path subFtpDirPath = Paths.get(ftpFileDir).resolve(dirName);
downloadFTPDirectory2Directory(ftpClient, subFtpDirPath.toString(), subOutDirPath);
}
}
}

// download ftp file (ftpFile) to directory (outDir)
private static void downloadFTPFile2Directory(FTPClient ftpClient, String ftpFile, Path outDirPath) throws IOException {
// 保证输出文件夹要存在
if (!Files.exists(outDirPath)) {
Files.createDirectories(outDirPath);
}
// ftpFile is full path
try (InputStream is = ftpClient.retrieveFileStream(ftpFile)) {
if (is != null) {
Path ftpFileNamePath = Paths.get(ftpFile).getFileName();
Path outPath = outDirPath.resolve(ftpFileNamePath);

int bufSize = 8 * 1024;
byte[] buffer = new byte[bufSize];
int len;

try (OutputStream os = Files.newOutputStream(outPath, StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {

while ((len = is.read(buffer)) > 0) {
os.write(buffer, 0, len);
}
}
}
}
ftpClient.completePendingCommand();
}

public static void main(String[] args) throws IOException {
String hostname = "192.168.1.2";
int port = 21;
String username = "ftpuser";
String password = "ftppass";

FTPClient ftpClient;
try {
ftpClient = FTPUtils.loginFTP(hostname, port, username, password);
downloadFromFTP(ftpClient, ".", "./dir");
// log out and disconnect from the server
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}

}
}