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

时间:2015-03-23 08:47:44

标签: java android

我正在尝试在我的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);失败。怎么了?我已经读过我能够在清单中设置更大的堆大小,但我觉得它不是一个好的解决方案。有什么问题?

3 个答案:

答案 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块