Проблемы с чтением огромного файла размером 12 МБ (java.lang.OutOfMemoryError)

Мне нужно открыть файл размером 12 мегабайт, но на самом деле я делаю это, создавая буфер размером 12834566 байт, потому что размер файла составляет 12 МБ, и я разрабатываю это приложение для мобильных систем Android.

Затем, я полагаю, мне нужно читать блоками по 1024 Кбайт вместо одного блока по 12 Мбайт с for, но я не знаю, как это сделать, мне нужна небольшая помощь.

Это мой фактический код:

File f = new File(getCacheDir()+"/berlin.mp3");
        if (!f.exists()) try {
          InputStream is = getAssets().open("berlin.mp3");
          int size = is.available();
          byte[] buffer = new byte[size];
          is.read(buffer);
          is.close();
          FileOutputStream fos = new FileOutputStream(f);
          fos.write(buffer);
          fos.close();
        } catch (Exception e) { throw new RuntimeException(e); }

Подскажите, пожалуйста, что мне нужно изменить в этом коде, чтобы читать блоки по 1024 Кбайт вместо одного блока по 12 Мбайт?

Спасибо!


person NullPointerException    schedule 12.12.2011    source источник
comment
Вы не можете создавать byte[] постепенно. Вы должны передавать данные туда, куда они идут, когда вы их читаете.   -  person Peter Lawrey    schedule 12.12.2011
comment
@ AndroidUser99 Хороший вопрос +1 для вас, сэр.   -  person Nikhil Agrawal    schedule 26.04.2013


Ответы (1)


Попробуйте скопировать по 1 КБ за раз.

File f = new File(getCacheDir()+"/berlin.mp3");
if (!f.exists()) try {
     byte[] buffer = new byte[1024];
     InputStream is = getAssets().open("berlin.mp3");
     FileOutputStream fos = new FileOutputStream(f);
     int len;
     while((len = is.read(buffer)) > 0) 
        fos.write(buffer, 0, len);
} catch (Exception e) { 
     throw new RuntimeException(e); 
} finally {
     IOUtils.close(is); // utility to close the stream properly.
     IOUtils.close(fos);
}

Поддерживает ли Android символические или ручные ссылки, такие как UNIX? Если это так, это будет быстрее/эффективнее.

person Peter Lawrey    schedule 12.12.2011
comment
Вы неправильно закрываете потоки. - person Marek Potociar; 12.12.2011
comment
@peter Larey отличный ответ, сэр. Решил мою проблему. +1 вам, сэр. - person Nikhil Agrawal; 26.04.2013