Плагин Ionic / Cordova File не может записать файл при последовательной загрузке большого количества документов на устройство iOS - PullRequest
0 голосов
/ 08 февраля 2019

Проблема, которую видит пользователь:

  1. У пользователя есть длинный список документов, которые необходимо загрузить на устройство iOS (200 +)
  2. Пользователь начинает загрузку с каждогофайл загружен подряд.
  3. В конце очереди на загрузку они обнаруживают, что один из файлов выходит из строя (и это всегда один из двух конкретных файлов размером 25 МБ +)
  4. Они повторяют задание (которое загружает толькодокумент потерпел неудачу), и он успешно

Что я вижу как разработчик:

  1. Мое приложение загружает документ в виде большого двоичного объекта
  2. Когда яосмотрите большой двоичный объект (в моем коде приложения Typescript), он имеет размер> 0
  3. , я звоню this.file.writeFile(directoryPath, fileName, blob, {replace: true}), который вызывает оболочку Ionic File вокруг плагина Cordova File
  4. Однако, когда я смотрюв BLOB-файле в write файла FileWriter.js он имеет нулевой размер
  5. . Все это приводит к ошибке, которая выдается в виде:
{"type":"error","bubbles":false,"cancelBubble":false,"cancelable":false,"lengthComputable":false,"loaded":0,"total":0,"target":{"fileName":"","length":0,"localURL":"cdvfile://localhost/persistent/downloaded-assets/9ce34f8a-6201-4023-9f5b-de6133bd5699/{{redacted}}","position":0,"readyState":2,"result":null,"error":{},"onwritestart":null,"onprogress":null,"onwriteend":null,"onabort":null}}

Что яИз этого следует, что где-то между вызовом file.writeFile для оболочки Ionic File в моем коде машинописи и метода FileWriter.write в пакете Cordova мой двоичный объект как-то поврежден, потерян или очищен.

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

Есть ли у нас какие-либо идеи, что может происходить здесь?Это проблема с памятью на iOS?Превышает ли Cordova тайм-аут по нескольким повторным запросам?

Несколько вещей, на которые следует обратить внимание:

  • Полный список файлов загружается каждый раз при попытке в симуляторе iOS xCode.Это наводит меня на мысль, что это может быть проблема с памятью, но я не уверен.

  • Ошибка всегда происходит после примерно 200 файлов и для одного из двух файлов, которые имеют 25-30MB +

Что касается отладки, то самое раннее, когда я вижу, что мой BLOB-объект уменьшен до 0, находится здесь https://github.com/apache/cordova-plugin-file/blob/4a92bbbea755aa9e5bf8cfd160fb9da1cd3287cd/www/FileWriter.js#L107 (хотя я могу отлаживать неправильно)

РЕДАКТИРОВАТЬ - После еще нескольких копаний я смог точно определить, где плагин Ionic вышел из строя:

Код, который я использовал:

  private writeFileInChunks(writer: FileWriter, file: Blob) {
    console.log('SIZE OF FILE AT START', file.size);
    const BLOCK_SIZE = 1024 * 1024;
    let writtenSize = 0;

    function writeNextChunk() {
      const size = Math.min(BLOCK_SIZE, file.size - writtenSize);
      console.log('CALCULATED SIZE:', size);
      const chunk = file.slice(writtenSize, writtenSize + size);
      console.log('SIZE OF CHUNK TO WRITE', chunk.size)
      writtenSize += size;
      writer.write(chunk);
    }

    return getPromise<any>((resolve, reject) => {
      writer.onerror = reject as (event: ProgressEvent) => void;
      writer.onwrite = () => {
        if (writtenSize < file.size) {
          writeNextChunk();
        } else {
          resolve();
        }
      };
      writeNextChunk();
    });
  }

Вывод для документа с ошибками:

SIZE OF FILE AT START: 34012899
CALCULATED SIZE: 1048576
SIZE OF CHUNK TO WRITE: 0

При повторной попытке:

SIZE OF FILE AT START: 34012899
CALCULATED SIZE: 1048576
SIZE OF CHUNK TO WRITE: 1048576
CALCULATED SIZE: 1048576
SIZE OF CHUNK TO WRITE: 1048576
...
...
...
CALCULATED SIZE: 458467
SIZE OF CHUNK TO WRITE: 458467

Так что по какой-то причине после большого количества предыдущих загрузок этот шаг file.slice приводит к пустой / поврежденной большой двоичной объекте.

Есть идеи, как это исправить?

Запустил еще один тест с некоторыми расширенными журналами:

  private writeFileInChunks(writer: FileWriter, file: Blob) {
    ...
    function writeNextChunk() {
      const size = Math.min(BLOCK_SIZE, file.size - writtenSize);
      console.log('CALCULATED SIZE:', size);
      console.log('WRITTEN SIZE', writtenSize);
      console.log('SUMS TO:', writtenSize + size)
      console.log('FILE SIZE BEFORE SLICE:', file.size);
      const chunk = file.slice(writtenSize, writtenSize + size);
      console.log('SIZE OF CHUNK TO WRITE', chunk.size);
      writtenSize += size;
      writer.write(chunk);
    }
    ...
    ...
  }

Вывод пришел к:

CALCULATED SIZE: 1048576
WRITTEN SIZE: 0
SUMS TO: 1048576
FILE SIZE BEFORE SLICE: 34012899
SIZE OF CHUNK TO WRITE 0

Дальнейшее подтверждение вопроса

...