Java FTPClient Stuck - PullRequest
       45

Java FTPClient Stuck

0 голосов
/ 17 декабря 2018

Я пытаюсь загрузить файл с моего ftp-сервера, но он зависает при их получении.Я использую commons-net-3.6.jar

То, что я заметил

Когда я использую ftpClient.enterRemotePassiveMode();
, в интерфейсе сервера FileZilla я вижу, что прогрессзагрузки для соединения, застрявшего на 76% (688 128 байт)

Когда я использую ftpClient.enterLocalPassiveMode();
, в интерфейсе сервера FileZilla я вижу, что процесс загрузки для соединения застрял на 96%(884 736 байт)

Интересно то, что в этих двух режимах он всегда застревает на одном и том же количестве байтов, независимо от того, что это за файл.Если размер файла превышает 884 736 или 688 128, он просто застревает.

Он отлично работает для файлов размером менее 884 736 байт в LocalPassiveMode и 688 128 байт в RemotePassiveMode.

Я пытался загрузить файл с другого сервера, но он не работал, так что он определенно не является серверомсвязанная с этим проблема.

Мой код

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 голосов
/ 17 декабря 2018

FTPClient # retrieveFileStream утверждает, что:

Вы должны закрыть InputStream, когда закончите чтение из него.Сам InputStream позаботится о закрытии родительского сокета подключения к данным после закрытия.

И

Чтобы завершить передачу файла, вы должны вызвать completePendingCommand и проверить его возвращаемое значениепроверить успех.Если этого не сделать, последующие команды могут вести себя неожиданно .


Вызовы должны быть завершены с использованием completePendingCommand, сейчас вывыполнение этого метода до финализации (вы читаете из inputStream после того, как вы позвонили completePendingCommand).

Также вы не закрываете свой 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
}
...