1

我正在使用这一段复制一个大文件。Android 在恰好 32 个缓冲区加载时因“内存不足”而崩溃。它的作用就像 dos.write 将数据放入一个大缓冲区而不是将其假脱机到 i/o 设备。不会抛出异常。

缓冲区大小 = 512*1024。bis 是一个 BufferedInputStream。byteArray 是一个 ByteArrayBuffer,

        try {
        FileOutputStream fos = new FileOutputStream(file);
        dos = new DataOutputStream(fos);

        int current = 0;

        while((current = bis.read()) != -1){
            byteArray.append((byte)current);
            if (byteArray.isFull()){
                byte[] b = byteArray.toByteArray();
                dos.write(b, 0, bufferSize);
                byteArray.clear();
                }
            }

        int count = byteArray.length();
        byte[] b = byteArray.toByteArray();
        dos.write(b, 0, count);
            dos.flush();
            dos.close();
            bis.close();
       }
         catch (Exception e) {
         RunTimeError("Exception: " + e);
         return false;
        }
4

1 回答 1

7

我的猜测是,由于某种原因,byteArray.isFull()它总是会返回。false然后,当您加载 16MB 数据时,您的内存不足。我不会打扰ByteArrayBuffer. (就此而言,512KB 对于这种操作来说太大了。你应该尝试匹配文件 I/O 块大小。它可能因设备而异,但 4K-8K 可能接近。)你也不要' t 需要包含fos在一个DataOutputStream; 你只是在写字节。BufferedOutputStream另一方面,A可能有用。如果bis没有缓冲,将其包装在 aBufferedInputStream中也会有所帮助。

我会像这样重写你的代码:

BufferedOutputStream bos = null;
try {
    bos = new BufferedOutputStream(new FileOutputStream(file), 8192);
    byte[] buffer = new byte[1024];

    int len = 0;

    while((len = bis.read(buffer)) != -1) {
        bos.write(buffer, 0, len);
    }
} catch (Exception e) {
     RunTimeError("Exception: " + e);
     return false;
} finally {
    try { bis.close(); } catch (Exception ignored) { }
    try { bos.close(); } catch (Exception ignored) { }
}
于 2012-06-06T03:03:38.917 回答