Приложение
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 байт. Лишь в редких случаях одно из изображений действительно загружается полностью, но это кажется довольно случайным.
Как мне это исправить, чтобы он полностью загружал все изображения?