В загруженных изображениях отсутствуют байты - PullRequest
0 голосов
/ 26 мая 2020
Приложение

My Android (Java 8, min SDK 24, target SDK 27) загружает изображения с FTP-сервера, используя Apache s FTPClient (версия 3.6).

Там это пара небольших изображений .jpg (около 12 КБ каждое), которые всегда загружаются полностью, но все большие изображения .png (8+ МБ каждое) отображаются в моем приложении черным цветом. Файлы на сервере выглядят нормально, поэтому я загрузил изображения из эмулятора:

Windows В приложении «Фото» внизу всех затронутых изображений отображается черная горизонтальная полоса, и все они отсутствуют. пара байтов (согласно Windows 'файловому проводнику).

Чтение загруженного изображения с BitmapFactory.decodeFile(....) на реальном устройстве возвращает null Bitmap, даже если файл существует.

Мой код (выполняется в фоновом потоке):

public void downloadFiles(String remoteFolder, String localFolder, ArrayList<String> filenames) {
    //login here
    ftpClient.setConnectTimeout(10000);
    ftpClient.setDefaultTimeout(10000);
    OutputStream out = null;

    try {
        ftpClient.enterLocalPassiveMode();
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE); 

        if(ftpClient.changeWorkingDirectory(remoteFolder)) {
            for(String filename : filenames) {
                FTPFile[] singleFile = ftpClient.listFiles(filename);

                if(singleFile != null && singleFile.length > 0) { //check if file exists
                    String localPath = localFolder + File.separator + filename;
                    out = new FileOutputStream(localPath);

                    if(!ftpClient.retrieveFile(filename, out)) {
                        //Set error message here
                        out.close();
                        break;
                    }

                    out.close();
                } else {
                    //Another error message here
                    break;
                }
            }
        }
    } catch (IOException e) {
        //And another error message here
    } finally {
        try {
            if(out!=null) { out.close(); }
        } catch(IOException e) {
            //Doesn't matter
        }
    }

    //logout here
}

Я пробовал out.flush() перед закрытием потока, более длительный тайм-аут (ftpClient.setDefaultTimeout(30000)) и даже retrieveFileStream:

InputStream is = ftpClient.retrieveFileStream(filename);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buf = new byte[10000000];
int len;

while ((len = bis.read(buf)) > 0) {
    out.write(buf, 0, len);
}

if(ftpClient.completePendingCommand()) {
    Log.d(TAG,"Done"); //This is always printed, even though the files aren't complete
} else {
    Log.d(TAG,"Not done");
}

out.close();
bis.close();

Проблема не устранена. Я добавил len и даже запустил bis.read еще пару раз (if(fullLength<singleFile[0].getSize())), но, несмотря ни на что, в большинстве случаев в загруженном файле отсутствует менее 10 байт. Лишь в редких случаях одно из изображений действительно загружается полностью, но это кажется довольно случайным.

Как мне это исправить, чтобы он полностью загружал все изображения?

...