Подтвердить что ты не робот

Огромный JavaScript HTML5 blob (из больших ArrayBuffers) для создания гигантского файла на стороне клиента

Я пишу приложение для веб-браузера (на стороне клиента), которое загружает огромное количество кусков из многих мест и присоединяется к ним для создания блоба. Затем этот blob сохраняется в локальной файловой системе как общий файл. То, как я это делаю, - это объекты ArrayBuffer и blob.

var blob = new Blob([ArrayBuffer1, ArrayBuffer2, ArrayBuffer3, ...], {type: mimetype})

Это нормально для файлов малого и среднего размера (до 700 МБ aprox), но браузер падает с большими файлами. Я понимаю, что память RAM имеет свои пределы. Дело в том, что мне нужно построить blob для создания файла, но я хочу, чтобы пользователи могли загружать файлы, размер которых намного больше, чем этот размер (представьте, например, файлы размером около 8 ГБ).

¿Как я могу построить blob, избегая ограничений по размеру? LocalStorage более ограничен RAM, поэтому я не знаю, что использовать или как это сделать.

4b9b3361

Ответ 1

Похоже, вы просто объединяете массивы данных вместе? Почему бы не объединить массивные буферы вместе в гигантском блобе. Вам придется перебирать и добавлять каждый массив по одному за раз. Вы бы seek до конца файла, чтобы добавить массивы. И для чтения только частей вашей гигантской капли назад вы получаете slice из blob, чтобы избежать сбоя браузера.

Добавление функции

function appendToFile(fPath,data,callback){
    fs.root.getFile(fPath, {
        create: false
    }, function(fileEntry) {
        fileEntry.createWriter(function(writer) {
            writer.onwriteend = function(e) {
                callback();
            };
            writer.seek(writer.length);
            var blob = new Blob([data]);
            writer.write(blob);
        }, errorHandler);
    }, errorHandler);
}

Снова, чтобы не читать весь капли назад, только читайте порции/куски вашего гигантского блоба при создании файла, который вы упоминаете.

Функция частичного чтения

function getPartialBlobFromFile(fPath,start,stop,callback){
    fs.root.getFile(fPath, {
        creation:false
    }, function(fileEntry){
        fileEntry.file(function(file){
            var reader = new FileReader();
            reader.onloadend = function(evt){
                if(evt.target.readyState == FileReader.DONE){
                    callback(evt.target.result);
                }
            };
            stop = Math.min(stop,file.size);
            reader.readAsArrayBuffer(file.slice(start,stop));
        }, errorHandler)
    }, errorHandler);
}

Возможно, вам придется хранить индексы, возможно, в разделе заголовка вашего гигантского BLOB - мне нужно будет узнать больше, прежде чем я смогу дать более точную обратную связь.


Обновление - исключение ограничений квот, временное и постоянное в ответ на ваши комментарии ниже
Похоже, что у вас возникают проблемы с квотой хранилища, потому что вы используете временное хранилище. Ниже приведен фрагмент, взятый из найденного google здесь

Временное хранилище доступно для всех веб-приложений, работающих в браузере. Общий пул может составлять до половины свободного места на диске. Хранение, уже используемое приложениями, включено в расчет общего пула; то есть расчет основан на (доступное пространство для хранения + хранилище, используемое приложениями) *.5.

Каждое приложение может иметь до 20% общего пула. Например, если общее доступное дисковое пространство составляет 50 ГБ, общий пул составляет 25 ГБ, а приложение может иметь до 5 ГБ. Это рассчитано от 20% (до 5 ГБ) в два раза (до 25 ГБ) доступного дискового пространства (50 ГБ).

Чтобы избежать этого ограничения, вам придется переключиться на постоянный, это позволит вам использовать квоту до доступного свободного места на диске. Для этого используйте следующее, чтобы инициализировать файловую систему вместо запроса временного хранения.

navigator.webkitPersistentStorage.requestQuota(1024*1024*5, 
  function(gB){
  window.requestFileSystem(PERSISTENT, gB, onInitFs, errorHandler);
}, function(e){
  console.log('Error', e);
})