Чтение большого файла небольшими порциями приводит к исключению OutOfMemory на Cordova- Android - PullRequest
0 голосов
/ 05 мая 2020

Я опубликовал это как проблему в файле-плагине cordova, но пока не получил ответа, поэтому я спрашиваю и здесь.

Эта проблема касается разбивки очень большой файл на устройстве android, на котором запущено приложение ionic4 + cordova.

Чтение фрагмента размером 5 МБ с использованием FileReader.readAsArrayBuffer для фрагмента (FileEntry.slice (x, y)) очень большого файла (2Gb +), вызывает OutOfMemory на Android (не тестировалось на iOS).

Конечная цель этого - загрузить большие файлы на наш сервер. Мы делаем это с разбиением файла на части по многим причинам (время загрузки, возобновление, проблемы с памятью и т. Д. c.). В нашем тесте весь файл считывался правильно, пока не достиг определенной точки, и приложение вылетало из-за исключения OutOfMemory. Чтение любой части до этого момента, кажется, работает нормально.

Я обнаружил некоторые проблемы, подобные этой, около net, но ни одна из них не смогла мне помочь. Я даже попытался применить исправление ЭТО , но безуспешно.

Я создал тестовый проект для проверки этого, который вы можете скачать ЗДЕСЬ . Он построен на Ionic4 и использует этот плагин (cordova-plugin-file) и cordova-plugin-filechooser для выбора файла.

ПРИМЕЧАНИЕ. Для выполнения этого проекта на вашем компьютере должны быть установлены ionic4 и cordova. Чтобы запустить его:

  1. Загрузить zip
  2. Извлечь zip
  3. открыть CMD, попасть в папку проекта
  4. запустить npm установить
  5. run ioni c cordova run android
  6. подключите свое android устройство или запустите android эмулятор
  7. запустите ioni c cordova run android
  8. Попав в проект, нажмите единственную кнопку; окно выбора файла должно открыться
  9. выберите файл размером больше 2050 МБ (чем больше, тем лучше)
  10. приложение должно вылететь; если вы посмотрите adb logcat, вы должны увидеть ошибку OutOfMemory

Не стесняйтесь поиграть с partStart и partEnd const, чтобы попробовать прочитать другие части файла.

Он читает файл из предоставленного URL-адреса с помощью resolveLocalFileSystemUrl, а затем использует фрагмент объекта «файл» в возвращенном FileEntry. Нарезанный большой двоичный объект (IFile с настроенным началом и концом, AFAIK) затем передается в функцию readAsArrayBuffer.

Ниже приведен код, который читает файл:

this.fileAPI.resolveLocalFilesystemUrl(filePath).then((fileEntry: FileEntry) => {

  fileEntry.file((file) => {

    const partStart = 2144337920;
    const partEnd = 2149580800;

    const reader = new FileReader();
    const blob = file.slice(partStart, partEnd);

    reader.onload = (event: any) => {
      if (event.target.readyState === FileReader.DONE) {
        console.log('READ COMPLETE');
        console.log(event.target.result);
      }
    };

    reader.readAsArrayBuffer(blob);

  }, (error) => {
    console.log('DEBUG - ERROR 3 ');
    console.log(error);

  });


}, (error) => {
  console.log('DEBUG - ERROR 5 ');
  console.log(error);

});

Это был протестирован на эмуляторе android со следующими характеристиками:

  • На основе устройства Pixel 2
  • Уровень API: 29 (Android Q)
  • Графика: Аппаратное обеспечение - GLES 2.0
  • Многоядерный процессор: 4
  • ОЗУ: 2048 Мб
  • Куча ВМ: 256 Мб
  • Внутренняя память: 10240 Мб
  • SD-карта: под управлением студии 512 Мб

Ioni c версия:

  • Ioni c CLI: 5.4.11 (C: \ Users \ User \ AppData \ Roaming \ npm \ node_modules \ ioni c)
  • Ioni c Framework: @ ionic / angular 5.0.7
  • @ angular - devkit / build- angular: 0.803.26
  • @ angular -devkit / schematics: 8.3.26
  • @ angular / cli: 8.3.26
  • @ ionic / angular -toolkit: 2.2.0

Версия Cordova:

Cordova CLI: 9.0.0 (cordova-lib@9.0.1) Cor Платформы dova: android 8.1.0 Плагины Cordova: cordova-plugin-ioni c -keyboard 2.2.0, cordova-plugin-ioni c -webview 4.1.3, (и 6 других плагинов)

Не стесняйтесь спрашивать подробности или любую информацию, которая может вам понадобиться. Большое спасибо.

...