Использование PhoneGap FileWriter.write для больших файлов

У меня проблема в приложении PhoneGap. Я хотел бы записать файл размером 15 МБ. Если я попытаюсь, ОС потребует все больше и больше памяти, и приложение вылетит без сообщения. Я могу воспроизвести это на планшетах Android и Blackberry. Есть ли способ реализовать написание более эффективно?

с уважением

fe.createWriter(
(fw: any) => {
    fw.onwriteend = (e) => {
        fw.onwriteend = (e) => {
            callback();
        }
        fw.write(data);
    }

    // write BOM (dead for now)
    fw.write("");
},
(error: any) => {
    alert("FileWriter Failed: " + error.code);
});

Это TypeScript, надеюсь, разработчики JS не будут с этим бороться ;)


person 4Str4ngeG4me    schedule 11.09.2013    source источник
comment
Куда вы записываете данные? а откуда данные? Если вы отправляете файл на сервер или получаете файл с сервера, вы можете проверить Передача файлов   -  person Jamie Starke    schedule 12.09.2013
comment
Данные поступили из базы данных (WebSQL), и я хотел бы записать их в файл на устройстве. Это своего рода резервный механизм.   -  person 4Str4ngeG4me    schedule 12.09.2013


Ответы (2)


Я нашел ответ.

Причина сбоя: PhoneGap FileWrite.write не может обрабатывать слишком большой буфер, не знаю точного размера, я думаю, что эта проблема связана с тем, что PG передает данные на iOS через схему URL, почему-то происходит сбой, когда «URL» слишком длинный.

Как это исправить: каждый раз писать небольшой блок, код ниже:

function gotFileWriter(writer) {
  function writeFinish() {
    // ... your done code here...
  }

  var written = 0;
  var BLOCK_SIZE = 1*1024*1024; // write 1M every time of write
  function writeNext(cbFinish) {
    var sz = Math.min(BLOCK_SIZE, data.byteLength - written);
    var sub = data.slice(written, written+sz);
    writer.write(sub);
    written += sz;
    writer.onwrite = function(evt) {
      if (written < data.byteLength)
        writeNext(cbFinish);
      else
        cbFinish();
    };
  }
  writeNext(writeFinish);
}

ОБНОВЛЕНИЕ 12 августа 2014 г.:

По моему опыту, производительность сохранения файла через файловую систему Cordova не очень хорошая, особенно для большого файла (> 5M) на телефоне это занимает несколько секунд. Если вы загружаете файл с сервера на локальный диск, вам может понадобиться «эффективный и прямой» способ, попробуйте cordova-plugin-file-transfer плагин.

person Imskull    schedule 12.12.2013
comment
Спасибо @Imskull. Это решает мою ту же проблему на Android. - person duckegg; 16.07.2014
comment
@Imskull: Спасибо за информацию, любая ссылка на документацию по написанию большого файла (›5M) - person Shankar; 13.08.2014
comment
Если данные представляют собой большой двоичный объект, вам нужно заменить .byteLength на .size. - person Sjoerd Pottuit; 07.12.2015
comment
@lmskull К сожалению, плагин FileTransfer не поддерживает почтовые данные. Допустим, вы загружаете защищенный файл и хотите отправить информацию для входа пользователя, чтобы подтвердить это. FileTransfer не поддерживает это. В моем случае я не могу найти другого решения, кроме FileWriter - person Ayman Abdel-Rahman; 26.05.2016

Ответ @Imskull правильный ... я просто хочу добавить один для Blob (убедитесь, что это blob, а не arraybuffer), который обновляется на основе того, что сверху ... я также добавил строку для Уверяю себя, я добавляю в конец файла... этого более чем достаточно, чтобы ваше приложение перестало падать (в основном на ios: P)

function gotFileWriter(writer) {
  function writeFinish() {
    // ... your done code here...
  }

  var written = 0;
  var BLOCK_SIZE = 1*1024*1024; // write 1M every time of write
  function writeNext(cbFinish) {
    writer.onwrite = function(evt) {
      if (written < data.size)
        writeNext(cbFinish);
      else
        cbFinish();
    };
    if (written) writer.seek(writer.length);
    writer.write(data.slice(written, written + Math.min(BLOCK_SIZE, data.size - written)));
    written += Math.min(BLOCK_SIZE, data.size - written);
  }
  writeNext(writeFinish);
}
person Wowzaaa    schedule 15.09.2016