我正在尝试在我的Android设备上下载文件。这是我的代码:
InputStream in = null;
ByteArrayOutputStream out = null;
FileOutputStream fos = null;
try {
URL link = new URL(fileURL);
in = new BufferedInputStream(link.openStream());
out = new ByteArrayOutputStream();
byte[] buf = new byte[8192];
int n, bytesBuffered = 0;
while (-1 != (n = in.read(buf))) {
bytesBuffered += n;
out.write(buf, 0, n);
if (bytesBuffered >1048576) {
bytesBuffered = 0;
out.flush();
}
}
byte[] response = out.toByteArray();
fos = new FileOutputStream(filePath);
fos.write(response);
return true;
} catch (Throwable e) {
e.printStackTrace();
return false;
} finally {
//closing streams
}
由于内存不足错误导致out.write(buf, 0, n);
失败。怎么了?我已经读过我能够在清单中设置更大的堆大小,但我觉得它不是一个好的解决方案。有什么问题?
答案 0 :(得分:1)
你做错了!
打开FileOutputStream
,只需从输入中读取并将其复制到输出流:
private static final int BUFSIZE = 8096;
//
final byte[] buf = new byte[BUFSIZE];
int nrBytes;
while ((nrBytes = in.read(buf)) != -1)
out.write(buf, 0, nrBytes);
(注意:关闭描述符不在这里处理,留作练习;但是sicne这是Android,因此你没有尝试使用资源甚至是JSR 203,我建议你使用Guava及其{{ 3}})
答案 1 :(得分:1)
如果您的目标是在文件上写入内容,则在编写内容之前无需读取内存中的内容。
fos = new FileOutputStream(filePath);
while (-1 != (n = in.read(buf))) {
bytesBuffered += n;
fos.write(buf, 0, n);
}
fos.flush();
我还会在try块中添加一个finally
子句来关闭fos。如果成功返回或发生错误,则调用finally块。这样您就不会泄漏FileOutputStream
答案 2 :(得分:0)
你需要一个do而不是while循环:
do {
n = in.read(buf);
bytesBuffered += n;
out.write(buf, 0, n);
if (bytesBuffered >1048576) {
bytesBuffered = 0;
out.flush();
}
} while (n != -1)
并添加一个由tony指出的finally块