繁体   English   中英

下载文件时出现java.lang.OutOfMemoryError

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM