问题代码:
FTPFile[] fs = ftpClient.listFiles(); for (FTPFile ff : fs) { if (ff.getName().equals(fileName)) { in = ftpClient.retrieveFileStream(fileName); } }
原因:
官方说法是:完成文件传输必须调用completependingcommand和检查它的返回值来验证成功。如果没有这样做,后续命令可能会意外地出错
简单来说:completePendingCommand()会一直在等FTP Server返回226 Transfer complete,但是FTP Server只有在接受到InputStream执行close方法时,才会返回。所以先要执行close方法
在使用public InputStream retrieveFileStream(String remote)
需要特别注意:
调用这个接口后,一定要手动close掉返回的InputStream,然后再调用completePendingCommand方法,若不是按照这个顺序,则会导致后面对FTPClient的操作都失败
解决方案:
1. 关闭流,调用completePendingCommand()方法
InputStream in = ftpClient.retrieveFileStream(fileName);
in.close();
ftpClient.completePendingCommand();
2. 生成临时文件转换层流返回
//生成临时文件 File tempFile = new File(localPath, localFileName); OutputStream outputStream = new FileOutputStream(tempFile); //检索指定从服务器上的文件并将其写入给定的输出流 ftpClient.retrieveFile(fileName, outputStream); outputStream.close(); InputStream inputStream = new FileInputStream(tempFile);
3 . 调用ftpClient.retrieveFile(fileName, outputStream)
File file = new File(filePath, fileName); OutputStream outputStream = new FileOutputStream(file); //检索指定从服务器上的文件并将其写入给定的输出流 ftpClient.retrieveFile(fileName, outputStream);