引:还是项目需要,要定时执行一个文件下载业务,一开始方向有点错,但是还好纠正过来了,采用ftp下载,但是ftp下载也有各种坑!
准备
jar包:commons-net
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
38public static boolean uploadFile(
String url,//服务器主机号
int port,//服务器端口
String username,//用户名
String password,//密码
String path, //上传路径Mar
String filename,//上传为服务器上的文件名
InputStream //input本地上传的文件流
) {
boolean success = false;
FTPClient ftp = new FTPClient();
try {
int reply;MarkDown
ftp.connect(url, port);//连接FTP服务器
//如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.login(username, password);//登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return success;
}
ftp.changeWorkingDirectory(path);
ftp.storeFile(filename, input);
input.close();
ftp.logout();
success = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return success;
}
测试代码:1
2
3File file = new File("/var/test.txt");
InputStream is = new FileInputStream(file);
uploadFile("127.0.0.1",21,"test","123456","/var/data/test","testdemo.txt",is);
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
63public static boolean downFile(
String url, //FTP服务器hostname
int port,//FTP服务器端口
String username, //FTP登录账号
String password, //FTP登录密码
String remotePath,//FTP服务器上的相对路径
String fileName,//要下载文件关键字
String localPath//下载后保存到本地的路径
) {
FTPClient ftpClient = null;
boolean success = false;
try {
ftpClient = new FTPClient();
ftpClient.connect(url, port);// 连接FTP服务器
ftpClient.login(username, password);// 登陆FTP服务器
ftpClient.setControlEncoding("gb2312"); // 中文支持
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//设置文件格式
ftpClient.enterLocalPassiveMode();
logger.info(ftpClient.getReplyCode());
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
logger.warn("未连接到FTP,用户名或密码错误。");
ftpClient.disconnect();
} else {
logger.info("FTP连接成功。");
}
ftpClient.changeWorkingDirectory(remotePath);
FTPFile[] fs = ftpClient.listFiles();
File file = new File(localPath);
if(!file.exists()){
file.mkdirs();
}
for(FTPFile ff:fs){
if(ff.getName().contains(fileName)){
File localFile = new File(localPath+"/"+ff.getName());
if (localFile.exists()){
continue;
}
OutputStream os = new FileOutputStream(localFile);
long time1 = System.currentTimeMillis();
boolean b = ftpClient.retrieveFile(new String(ff.getName().getBytes("gb2312"),"ISO8859-1"), os);
os.flush();
os.close();
}
}
ftpClient.logout();
success = true;
} catch (SocketException e) {
e.printStackTrace();
logger.warn("FTP的IP地址可能错误,请正确配置。");
} catch (IOException e) {
e.printStackTrace();
logger.warn("FTP的端口错误,请正确配置。");
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException ioe) {
}
}
}
return success;
}
测试程序:1
downFile("127.0.0.1",21,"test","123456","、var/data/test","demo","/var/alldata");
一些坑
客户端接受的编码
1
ftpClient.setControlEncoding("gb2312"); // 中文支持
如果服务器上的文件名有中文,一定要加上这一句,具体编码要根据服务器的编码。
客户端接受的文件类型
1
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//设置文件格式
文件类型要根据下载的文件格式来定
服务器端口设置
1
ftpClient.enterLocalPassiveMode();
调用FTPClient.enterLocalPassiveMode();这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据,防止在新端口对外部不通,因为ftp server可能每次开启不同的端口来传输数据,但是在linux上,由于安全限制,可能某些端口没有开启,所以就出现阻塞。
最大的坑(下载出0kb的文件:实质就是retrieveFile方法执行失败)
1
ftpClient.retrieveFile(new String(ff.getName().getBytes("gb2312"),"ISO8859-1"), os)
一定要给文件名换编码,让它识别中文,具体编码也是根据实际情况而定。
总结
ftp客户端的速度也是要根据网速来的,可能比一般http快,但是面对网速慢的情况也是无可奈何!