Чтение нескольких файлов в цикле с FTP-сервера с использованием Apache Commons Net FTPClient - PullRequest
1 голос
/ 30 сентября 2019

У меня есть список файлов, которые необходимо прочитать с FTP-сервера. У меня есть метод readFile(String path, FTPClient client), который читает и печатает файл.

public byte[] readFile(String path,FTPClient client){
    InputStream inStream = null;
    ByteArrayOutputStream os = null;
    byte[] finalBytes = new byte[0];
            int reply;
    int len;
    byte[] buffer = new byte[1024];
    try{
        os = new ByteArrayOutputStream();
        inStream = client.retrieveFileStream(path);
        reply = client.getReplyCode();
        log.warn("In getFTPfilebytes() :: Reply code -"+reply);

        while ((len = inStream.read(buffer)) != -1) {
                    // write bytes from the buffer into output stream
                    os.write(buffer, 0, len);
                }
        finalBytes = os.toByteArray();

    if(inStream == null){
        throw new Exception("File not found");
    }

    inStream.close();
    }catch(Exception e){

    }finally{
        try{ inStream.close();} catch(Exception e){}
    }
    return finalBytes;

}

Я вызываю вышеуказанный метод в цикле списка, который содержит строки пути к файлу.

Проблема - только в циклеПервый файл читается правильно. После этого он не читает файл и выдает исключение. inStream дает NULL для второй итерации / второго файла. Кроме того, при повторении первого кода ответа код файла после retrieveFileStream равен "125 (Соединение для передачи данных уже открыто; передача начинается.) "

Во второй итерации выдается "200 (Запрошенныйдействие было успешно завершено.) "

Я не могу понять, что здесь не так. Не правильно закрыли inputstream соединение?

Ответы [ 3 ]

1 голос
/ 30 сентября 2019

Согласно документации метода FTPClient.retrieveFileStream() ,

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

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

0 голосов
/ 30 сентября 2019

Вы должны вызвать FTPClient.completePendingCommand и закрыть входной поток, поскольку документация для FTPClient.retrieveFileStream говорит:

Возвращает InputStream изкоторый именованный файл с сервера можно прочитать. Если текущий тип файла - ASCII, возвращенный InputStream преобразует разделители строк в файле в локальное представление. Вы должны закрыть InputStream, когда закончите чтение из него. Сам InputStream позаботится о закрытии сокета родительского подключения к данным после закрытия.

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


inStream = client.retrieveFileStream(path);
try {
    while ((len = inStream.read(buffer)) != -1) {
                // write bytes from the buffer into output stream
                os.write(buffer, 0, len);
            }
    finalBytes = os.toByteArray();
} finally {
    inStream.close()
    if (!client.completePendingCommand()) {
        // error
    }
}
0 голосов
/ 30 сентября 2019
  1. Я не видел, что выходной поток не закрыт должным образом.
  2. finalBytes - это o байты?
  3. где вы определили переменную буфера?

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

...