简体   繁体   English

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

[英]java.lang.OutOfMemoryError while downloading file

I'm trying to download file at my android device. 我正在尝试在Android设备上下载文件。 This is my code: 这是我的代码:

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
}

It fails at out.write(buf, 0, n); 它在out.write(buf, 0, n);处失败out.write(buf, 0, n); with out of memory error. 内存不足错误。 What is wrong? 怎么了? I've read I'm able to set bigger heap size at manifest, but I don't find it a good solution. 我读过我可以在清单中设置更大的堆大小,但是我找不到一个好的解决方案。 What is wrong? 怎么了?

You are doing it wrong! 你做错了!

Open your FileOutputStream and just read from the input and copy it to the output stream: 打开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);

(note: closing descriptors not handled here, left as an exercise; but sicne this is Android and you therefore don't have try-with-resource or even JSR 203, I suggest you use Guava and its Closer ) (注意:此处未处理关闭描述符,请作为练习;但由于这是Android,因此您没有try-with-resource甚至JSR 203,我建议您使用Guava及其Closer

if your goal is to write the content on a file, there is no need to read the content in memory before writing it. 如果您的目标是将内容写入文件,则在写入之前无需读取内存中的内容。

fos = new FileOutputStream(filePath);
while (-1 != (n = in.read(buf))) {
    bytesBuffered += n;
    fos.write(buf, 0, n);
}
fos.flush();

and I would also add a finally clause to the try block to close fos. 并且我还将在try块中添加一个finally子句以关闭fos。 The finally block is call either if you return successfully or if an error occurs. 如果成功返回或发生错误,则调用finally块。 This way you will not leak the FileOutputStream 这样,您就不会泄漏FileOutputStream

You need a do instead of a while loop : 您需要一个do而不是while循环:

do {    
    n = in.read(buf); 
    bytesBuffered += n;
    out.write(buf, 0, n);
    if (bytesBuffered >1048576) {
        bytesBuffered = 0;
        out.flush();
    }
} while (n != -1)

and also add a finally block as pointed out by tony 并按照tony的说明添加一个finally块

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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