Downloaded images are missing bytes

可紊 提交于 2020-12-23 12:11:54

问题


My Android app (Java 8, min SDK 24, target SDK 27) downloads images from an FTP server, using Apache's FTPClient (version 3.6).

There are a couple of smaller .jpg images (around 12kb each) that always download completely but all of the bigger .png images (8+ mb each) show up black in my app. The files on the server look fine, so I downloaded the images from the emulator:

Windows' "Photo" app displays a black, horizontal bar at the bottom of all the affected images and they are all missing a couple of bytes (according to Windows' file explorer).

Reading the downloaded image with BitmapFactory.decodeFile(....) on a real device returns a null Bitmap, even though the file exists.

My code (runs on a background thread):

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
}

I tried out.flush() before closing the stream, a longer timeout (ftpClient.setDefaultTimeout(30000)) and even 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();

The problem persists. I added up len and and even ran bis.read a couple more times (if(fullLength<singleFile[0].getSize())) but no matter what, most of the time less than 10 bytes are missing in the downloaded file. Only rarely one of the images is actually downloaded completely but it seems to be pretty random.

How do I fix this, so it downloads all of the images completely?

来源:https://stackoverflow.com/questions/62023585/downloaded-images-are-missing-bytes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!