FtpClient retrieveFileStream [зависает]

1

У меня есть локальный FTP-сервер (созданный с сервером FileZilla), и есть несколько файлов XLS. Мне нужно вернуть поток ввода файла в мое приложение Java, чтобы я мог разбирать данные и т.д.

Для этого я попытался использовать FTPClient, но по какой-то причине при попытке вернуть входной поток из файлов (больше 40 КБ или) зависает FTPClient.retrieveFileStream().

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

Соответствующие части кода:

public FTPwrapper(){

    ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    Properties props = (Properties) context.getBean("ftp_props");

    this.FTPhost = props.getProperty("host");
    this.FTPuser = props.getProperty("user");
    this.FTPpass = props.getProperty("pass");
    this.FTPport = Integer.parseInt(props.getProperty("port"));
    this.filesPath = props.getProperty("filesPath");
    //start ftp connection
    try {
        client.connect(this.FTPhost, this.FTPport);
        client.login(this.FTPuser, this.FTPpass);
        client.setBufferSize(1024 * 1024);
        client.enterLocalPassiveMode();
        client.setFileType(FTP.BINARY_FILE_TYPE);
    } catch (IOException e) {
       e.printStackTrace();
    } 
}

public InputStream returnFileStream(String FileName){

    InputStream inputstream = null;

    try {
        String remoteFile = this.filesPath+FileName;
        inputstream = client.retrieveFileStream(remoteFile);
        client.completePendingCommand();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (client.isConnected()) {
                client.logout();
                client.disconnect();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }      

    return inputstream;
}

public static void main(String[] args){ 
    FTPwrapper ftp = new FTPwrapper(); 
    InputStream inputstream = ftp.returnFileStream("2012 m muzieju statistika.xls");
}

Журнал FPT:

...login commands...
227 Entering Passive Mode
RETR /vtipsis_data/KT/2012 m muzieju statistika.xls
50 Opening data channel for file download from server of "/vtipsis_data/KT/2012 m muzieju statistika.xls"  //Hangs...

После того, как ftp-соединение, наконец, закончилось, я получаю исключение java:

java.io.IOException: Your file contains 383 sectors, but the initial DIFAT array at index 4 referenced block # 505. This isn't allowed and  your file is corrupt
    at org.apache.poi.poifs.storage.BlockAllocationTableReader.<init>(BlockAllocationTableReader.java:103)
    at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:151)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:322)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:303)

Я предполагаю, что это исключение связано с возвратом только части моего входного потока файла XLS. Так вот, моя проблема. Есть идеи, как это решить?

  • 0
    Просто сказать спасибо ... и показать мою признательность: тот, кто не хочет использовать PowerMock и предпочел бы переписать код, чтобы избавиться от статических вызовов, должен быть хорошим человеком ;-)
Теги:
ftp
inputstream

1 ответ

4

Это не тот ответ, который я хотел, но обходной путь, который должен быть достаточным... Вместо того, чтобы пытаться напрямую извлекать поток, используя retrieveFileStream, я использовал retrieveFile для загрузки файла в качестве временного системного файла и преобразовал OutputStream, который я получил от retrieveFile для InputStream. После этого я просто удаляю загруженный временный файл.

Пробовал использовать it.sauronsoftware.ftp4j, но у него нет метода/функции, подобного retrieveFileStream и он может загружать только файл.

РЕДАКТИРОВАТЬ:

Я нашел способ вернуть входной поток файла без использования retrieveFileStream или загрузки файла. Поскольку retrieveFile возвращает OutputStream, я могу просто преобразовать OutputStream в InputStream (почему я не думал об этом раньше?), Например:

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
client.retrieveFile(remoteFile, outputStream);
InputStream inputstream = new ByteArrayInputStream(outputStream.toByteArray());

Ещё вопросы

Сообщество Overcoder
Наверх
Меню