JAVA实现FTP批量下载数据只下载第一个路径的附件问题记录

问题描述:

项目要求从FTP服务器根据上传的路径批量获取附件存储到本地,这里我用的是org.apache.commons.net.ftp.FTPClient来实现ftp的连接,我定义了一个FtpConnection类用来包装初始化FTPClient、下载文件和删除文件的方法。

public class FtpConnection {
    private FTPClient ftpClient = new FTPClient();

    public FTPClient init(FtpProperties properties) {
        try {
            log.info("connecting...ftp服务器[{}]", properties.getHost() + ":" + properties.getPort());
            ftpClient.connect(properties.getHost(), properties.getPort());
            ftpClient.login(properties.getUsername(), properties.getPassword());
            int replyCode = ftpClient.getReplyCode(); //是否成功登录服务器
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                ftpClient.disconnect();
                System.out.println("connect failed...");
            }
            if (replyCode == 1) {
                ftpClient.enterLocalActiveMode();//主动模式
            } else if (replyCode == 2) {
                ftpClient.enterLocalPassiveMode(); //被动模式
            }
            ftpClient.setControlEncoding("GBK");//中文支持
            ftpClient.sendCommand("OPTS UTF8", "ON");
            log.info("connect successful...ftp serer:{}:{}", properties.getHost(), properties.getPort());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ftpClient;
    }

    ...
}

然后通过对路径的遍历下载文件

for (String filePath : filePaths) {
            int index = 0;
            //判断路径下的文件是否存在
            if (!connection.existFile(filePath)) {
                log.info("路径:{}文件不存在", filePath);
                continue;
            }
            //根据文件路径获取文件名称
            String fileName = getFileName(filePath);
            //根据ftp的文件路径获取文件流
            InputStream inputStream = connection.downloadFile(filePath);
            if (inputStream != null) {
                //执行业务逻辑
            }
            index++;
        }

但是通过这种方式永远都只能下载到第一次遍历的文件,第二个路径的文件就会提示不存在,于是我就在每一次遍历的时候都把connection执行init()一次,这样虽然可以拿到文件,但是这种重复的连接ftp服务器应该会有一些隐患在里面。在后来看其它博主的博客后才找到问题原因:

for (String filePath : filePaths) {
            int index = 0;
            //判断路径下的文件是否存在
            if (!connection.existFile(filePath)) {
                log.info("路径:{}文件不存在", filePath);
                continue;
            }
            //根据文件路径获取文件名称
            String fileName = getFileName(filePath);
            //根据ftp的文件路径获取文件流
            InputStream inputStream = connection.downloadFile(filePath);
            if (inputStream != null) {
                //执行业务逻辑
            }
           /*
            * 官方说法是:完成文件传输必须调用completePendingCommand和检查它的返回值
            * 来验证成功。如果没有这样做,后续命令可能会意外出错
            * 简单来说:completePendingCommand()会一直等FTP Server返回226
            * Transfer complate,但是FTP Server只有在接收InputStream执行close()方法的时候,
            * 才会返回。所以要先执行close()方法。
            */
            inputStream.close();
            connection.getFtpClient().completePendingCommand();
            index++;
        }

我的理解是,在获取流执行完业务流程后需要关闭流并且执行completePendingCommand()方法,FTP服务器才会判断这一次获取流的动作算是完成,如果没有这个完成动作,下一次获取流就会一直读到空的InputStream,所以就会判断文件不存在。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值