Java FTPClient卡住

时间:2018-12-17 19:18:53

标签: java ftp file-transfer ftp-client apache-commons-net

我正在尝试从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;

   }


}

1 个答案:

答案 0 :(得分:2)

FTPClient#retrieveFileStream指出:

  

完成从InputStream的读取后,您必须关闭它。的   InputStream本身将负责关闭父数据   关闭连接插座。

  

要完成文件传输,必须调用completePendingCommand和   检查其返回值以验证成功。如果不这样做,   后续命令可能会意外


应该使用completePendingCommand

调用进行终结,现在,您要在终结之前执行该方法(您正在从inputStream阅读致电completePendingCommand之后。

您也不会关闭它特别声明的inputStream


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

inputStream