写点什么

java 实现 FTP 下载,解决假死问题

作者:Steven
  • 2023-02-01
    河南
  • 本文字数:1542 字

    阅读完需:约 5 分钟

(1)在请求 FTP 服务进行下载文件时,需要循环遍历文件夹获取文件进行解析,但是在 in = ftpClient.retrieveFileStream(file.getName());

时,输入流总是获取到 null,一定要执行 in.close();关闭输出流之后,再执行 ftpClient.completePendingCommand();传输结束方法。

(2)FTP 服务使用的是 window 系统,在本地建了 window 虚拟机使用的是 window 开发,进行远程 ftp 访问是没有问题的数据能够解析并且入库,但是部署到 LINUX 系统后,在 retrieveFileStream 方法出现了线程阻塞,连接 ftp 服务的线程挂起。在 ftp 连接时,ftpClient.enterLocalPassiveMode(); 设置为被动传输模式就可以解决线程挂起问题。

(3)在使用 java,通过 FTP 下载文件,发现在下载过程中,程序出现假死的现象,就是既不报错,也不抛异常,还不终止,就是一直在跑服务,在这里分享下解决方案:

FTPClent 需要使用被动模式:

在调用 FTPClient.listFiles()或者 FTPClient.retrieveFile()方法前,调用 FTPClient.enterLocalPassiveMode()!

也就是说:“这个方法的意思就是每次数据连接之前,ftp client 告诉 ftp server 开通一个端口来传输数据。”

为什么要这样做呢,因为 FTPServer 可能每次开启不同的端口来传输数据,但是在 linux 上,由于安全限制,可能某些端口没有开启,所以就出现阻塞.

代码 1 如下:

//创建 FTP 连接

ftpClient.setDefaultPort(//FTP 端口号);

ftpClient.connect(//FTP 服务 IP 地址);

ftpClient.login(//FTP 用户名, //密码);

ftpClient.setBufferSize(1024);

//设置文件类型(二进制)

ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

//每次数据连接之前,ftp client 告诉 ftp server 开通一个端口来传输数据

ftpClient.enterLocalPassiveMode();

//从 FTP 下载文件

boolean b = ftpClient.retrieveFile(//FTP 文件路径及文件名, //用以保存文件的文件输出流);

==========================华丽分割线==========================

代码 2 如下:

//ftp 指定目录下的 AEI 文件夹数组

FTPFile[] ftpDirectory = ftpClient.listFiles();

//循环遍历子文件夹下的所有文件

for(int i = 0;i < ftpDirectory.length;i++) {

//获取一个子文件夹

FTPFile oneDirectory = ftpDirectory[i];

//判断是否是文件夹

if(oneDirectory.isDirectory()){

//改变工作目录到指定目录的子文件夹

ftpClient.changeWorkingDirectory(oneDirectory.getName());

//获取子文件夹的所有报文

FTPFile[] files = ftpClient.listFiles();

//获取自目录下的报文

for(FTPFile file : files){

//D 报文获取

if("D".equals(file.getName().substring(0, 1))){

//获取输入流

in = ftpClient.retrieveFileStream(file.getName());

//根据文件名将对应输入流转换为字符流

br = new BufferedReader(new InputStreamReader(in));

//将文件名与文件内容的第一行赋予待解析报文 Map,防止 map 的 key 重复,将文件内容作为 key

filesMap.put(br.readLine(), file.getName());

//关闭输入流

in.close();

//ftp 传输结束

ftpClient.completePendingCommand();

//添加该文件到要删除源文件的报文集合

delFilesList.add("\\"+oneDirectory.getName()+"\\"+file.getName());

}

}

//将工作目录改回原指定目录,为了遍历下一个子文件夹

ftpClient.changeToParentDirectory();

}

}

//关闭 ftp 连接

ftpClient.disconnect();

//关闭字符缓冲输入流

if(br != null){

br.close();

}

发布于: 刚刚阅读数: 4
用户头像

Steven

关注

还未添加个人签名 2023-01-09 加入

还未添加个人简介

评论

发布
暂无评论
java实现FTP下载,解决假死问题_Steven_InfoQ写作社区