如何将应用程序资产文件夹中的大文件写入SD卡而不会出现内存不足错误?

Rua*_*ien 1 java file-io android out-of-memory

我正在尝试将大约80兆字节的文件从Android应用程序的assets文件夹复制到SD卡.

该文件是另一个apk.由于各种原因,我必须这样做,不能简单地链接到在线apk或把它放在Android市场上.

该应用程序适用于较小的apks,但对于这个大的,我得到一个内存不足的错误.

我不确定这是如何工作的,但我假设在这里我试图写入完整的80兆内存.

try {
                int length = 0;
                newFile.createNewFile();

                InputStream inputStream = ctx.getAssets().open(
                        "myBigFile.apk");
                FileOutputStream fOutputStream = new FileOutputStream(
                        newFile);
                byte[] buffer = new byte[inputStream.available()];
                while ((length = inputStream.read(buffer)) > 0) {
                    fOutputStream.write(buffer, 0, length);
                }
                fOutputStream.flush();
                fOutputStream.close();
                inputStream.close();
            } catch (Exception ex) {
                if (ODP_App.getInstance().isInDebugMode())
                    Log.e(TAG, ex.toString());
            } 
Run Code Online (Sandbox Code Playgroud)

我发现这很有趣 - 关于Bitmaps的内存不足问题

除非我误解了,在Bitmaps的情况下,似乎有一些方法可以使用BitmapFactory.Options拆分流以减少内存使用量.

这在我的方案中是否可行或是否有其他可能的解决方案?

Ale*_*s G 7

诀窍不是一次性尝试读取整个文件,而是在小块中读取它并在将每个块读取到同一个内存段之前写入每个块.以下版本将以1K块的形式读取它.仅举例来说 - 您需要确定正确的块大小.

try {
    int length = 0;
    newFile.createNewFile();

    InputStream inputStream = ctx.getAssets().open(
            "myBigFile.apk");
    FileOutputStream fOutputStream = new FileOutputStream(
            newFile);
    //note the following line
    byte[] buffer = new byte[1024];
    while ((length = inputStream.read(buffer)) > 0) {
        fOutputStream.write(buffer, 0, length);
    }
    fOutputStream.flush();
    fOutputStream.close();
    inputStream.close();
} catch (Exception ex) {
    if (ODP_App.getInstance().isInDebugMode())
        Log.e(TAG, ex.toString());
} 
Run Code Online (Sandbox Code Playgroud)