Как записать большой файл из папки ресурсов приложения на SD-карту без ошибки «Недостаточно памяти»? - PullRequest
1 голос
/ 11 января 2012

Я пытаюсь скопировать файл размером около 80 мегабайт из папки активов приложения Android на SD-карту.

Файл является другим 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());
            } 

Я нашел это интересным - Вопрос о проблеме нехватки памяти с растровыми изображениями

Если я неправильно понял, в случае с битмапами, существует некоторый способ разделить поток, чтобы уменьшить использование памяти с помощью BitmapFactory.Options.

Это выполнимо в моем сценарии или есть другое возможное решение?

Ответы [ 2 ]

7 голосов
/ 11 января 2012

Хитрость заключается не в том, чтобы попытаться прочитать весь файл за один раз, а в том, чтобы прочитать его небольшими порциями и записать каждый кусок перед тем, как читать следующий в тот же сегмент памяти.Следующая версия будет читать это в 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());
} 
2 голосов
/ 11 января 2012

Не читать весь файл в память; читать 64k за раз, затем написать их, повторять, пока не дойдете до конца файла. Или используйте IOUtils из Apache Commons IO.

...