我的Android应用(Java 8,最小SDK 24,目标SDK 27)从FTP服务器下载图片,使用Apache的 FTPClient
(3.6版本)。
有几个较小的.jpg图片(每张约12kb)总是完全下载,但所有较大的.png图片(每张8+mb)在我的应用程序中显示为黑色。服务器上的文件看起来很好,所以我从模拟器上下载了这些图片。
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个字节。只有很少的情况下,其中一张图片才会被完全下载,但这似乎是很随机的。
我如何解决这个问题,让它完全下载所有的图片?