Java FTPClient 卡住

Java FTPClient Stuck

我正在尝试从我的 ftp 服务器下载文件,但在检索文件时卡住了。我正在使用 commons-net-3.6.jar

我注意到的事情

当我使用 ftpClient.enterRemotePassiveMode();
我可以在 FileZilla 服务器界面看到连接下载进度卡在 76%(688,128 字节)

当我使用 ftpClient.enterLocalPassiveMode();
我可以在 FileZilla 服务器界面看到连接下载进度卡在 96%(884,736 字节)

有趣的是,在这两种模式下,无论文件是什么,它总是卡在完全相同的字节数上。如果文件大小大于 884,736 或 688,128,它就会卡住。

对于 LocalPassiveMode 小于 884,736 字节和 RemotePassiveMode 小于 688,128 字节的文件,它非常适用。

我试过从不同的服务器下载但没有成功,所以这绝对不是服务器相关的问题。

我的代码

public class FTPDownload {

private List<BufferedImage> imageList;
private boolean wasConnected;


public void getFiles(String orderRootDirectory){

    wasConnected = true;

    imageList = new ArrayList<>();
    FTPConnection con = new FTPConnection(); // to get the FTP Credentials
    con.readData();
   try {
       FTPClient ftpClient = new FTPClient();
       ftpClient.connect(con.getServerIp());
       ftpClient.enterLocalPassiveMode();

       ftpClient.login(con.getUsername(), con.getPassword());
       ftpClient.setAutodetectUTF8(true);
       ftpClient.setBufferSize(1024 * 1024); // tried with and without this no luck there

       wasConnected = ftpClient.isConnected();

       FTPFile[] files = ftpClient.listFiles(orderRootDirectory);

       for (FTPFile file : files) {
           String details = file.getName();


           if (file.isDirectory()) {
               details = "[" + details + "]";
           }

           String totalFilePath = orderRootDirectory+"/"+file.getName();



           InputStream inputStream = ftpClient.retrieveFileStream(totalFilePath);  // stuck over here

           System.out.println(ftpClient.completePendingCommand());
           System.out.println(ftpClient.getReplyString());

           System.out.println("Reading File...");
           long start=System.currentTimeMillis();
           ImageIO.setUseCache(false);
           BufferedImage bimg = ImageIO.read(inputStream);


           long end=System.currentTimeMillis();
           System.out.println("time="+(end-start));


           imageList.add(bimg);

           details += "\t\t" + file.getSize();
           details += "\t\t" + file.getName();
           System.out.println(details);
       }

       System.out.println(imageList.size());

       ftpClient.logout();
       ftpClient.disconnect();
   }catch (Exception e){

       e.printStackTrace();
       wasConnected = false;

   }


}

FTPClient#retrieveFileStream 表示:

You must close the InputStream when you finish reading from it. The InputStream itself will take care of closing the parent data connection socket upon being closed.

To finalize the file transfer you must call completePendingCommand and check its return value to verify success. If this is not done, subsequent commands may behave unexpectedly.


调用应该 finalized 使用 completePendingCommand,现在你正在执行那个方法 before finalizing(你正在调用 completePendingCommand 后从 inputStream 读取。

此外,您没有关闭它明确指出的 inputStream


要解决您的问题,请执行以下操作,我们首先关闭 inputStream,然后调用 completePendingCommand,所有这些都应该在 之后发生已阅读 inputStream.

InputStream inputStream = ftpClient.retrieveFileStream(totalFilePath);

BufferedImage bimg = ImageIO.read(inputStream);

inputStream.close();
if (!ftpClient.completePendingCommand()) {
    // Throw some error or do something, file transfer failed
}