1

大きなファイルをコピーするこのセグメントを使用しています。Androidは、正確に32のバッファロードで「メモリ不足」でクラッシュします。これは、dos.writeがデータをI / Oデバイスにスプールするのではなく、大きなバッファに入れるように機能します。例外はスローされません。

bufferSize = 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()戻ってきます。false16MB のデータをロードすると、メモリ不足になります。私は気にしませんByteArrayBuffer。(さらに言えば、512KB はこの種の操作にはバッファが大きすぎます。ファイル I/O ブロック サイズを一致させるようにしてください。おそらくデバイスによって異なりますが、4K-8K はおそらく近いです。) ;でラップする必要fosはありません。DataOutputStreamあなたはバイトを書いているだけです。BufferedOutputStream一方、Aは便利かもしれません。また、bisバッファリングされていない場合は、ラップするBufferedInputStreamことも役立ちます。

私はあなたのコードを次のように書き直します:

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 に答える