![](/img/trans.png)
[英]java.lang.OutOfMemoryError: Java heap space while downloading a large file from an URL
[英]java.lang.OutOfMemoryError while downloading file
我正在尝试在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);
处失败out.write(buf, 0, n);
内存不足错误。 怎么了? 我读过我可以在清单中设置更大的堆大小,但是我找不到一个好的解决方案。 怎么了?
你做错了!
打开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);
(注意:此处未处理关闭描述符,请作为练习;但由于这是Android,因此您没有try-with-resource甚至JSR 203,我建议您使用Guava及其Closer
)
如果您的目标是将内容写入文件,则在写入之前无需读取内存中的内容。
fos = new FileOutputStream(filePath);
while (-1 != (n = in.read(buf))) {
bytesBuffered += n;
fos.write(buf, 0, n);
}
fos.flush();
并且我还将在try块中添加一个finally
子句以关闭fos。 如果成功返回或发生错误,则调用finally块。 这样,您就不会泄漏FileOutputStream
您需要一个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块
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.