Сохранять данные, сгенерированные клиентом как файл в JavaScript в кусках

Я разрабатываю приложение FileShare с webRTC. Я хочу реализовать клиента в JavaScript/HTML. Код должен запускаться в браузере клиентов. Мне нужно сохранить их при загрузке через webRTC. Файлы могут быть довольно большими, и я не могу полностью загрузить их и сохранить их в массиве или блоке, прежде чем сохранять их на диск в виде файла.

Есть ли какой-либо API, который позволяет мне сохранять файл в кусках по мере их получения?

Я нашел до сих пор Downloadify, FileSave.js и html5 FileWriterApi. В то время как первые два не чередуются и требуют, чтобы я сначала загрузил полный файл в память перед сохранением, FileWriterAPI недоступен в большинстве браузеров.

Ответ 1

Как предположил @jordan-grey, сохранение кусков в blobs и объединение их в более крупный blob может быть решением, если:

  • Сохранение кусков не требуется (т.е. закрытие браузера удалит все фрагменты)
  • Файл сохраняется только пользователем, сохраняющим его в своей файловой системе. Веб-приложение не будет иметь доступ к файлу после его закрытия, если только пользователь не предоставил доступ к сохраненному файлу снова.
  • Возможно, если размеры файлов не слишком велики (вам нужно будет проверить это, чтобы узнать это). Хром вел себя неплохо для меня для кусков на 1 ГБ.

Я создал простой тест для использования капли в виде кусков. Вы можете играть с разными параметрами размера и количества блоков:

var chunkSize = 500000;
var totalChunks = 200;
var currentChunk = 0;
var mime = 'application/octet-binary';
var waitBetweenChunks = 50;

var finalBlob = null;
var chunkBlobs =[];

function addChunk() {
    var typedArray = new Int8Array(chunkSize);
    chunkBlobs[currentChunk] = new Blob([typedArray], {type: mime});
    console.log('added chunk', currentChunk);
    currentChunk++;
    if (currentChunk == totalChunks) {
        console.log('all chunks completed');
        finalBlob = new Blob(chunkBlobs, {type: mime});
        document.getElementById('completedFileLink').href = URL.createObjectURL(finalBlob);
    } else {
        window.setTimeout(addChunk, waitBetweenChunks);
    }
}
addChunk();

Если вам нужна эта настойчивость, W3C File System API должен поддерживать то, что вам нужно. Вы можете использовать его для записи фрагментов для разделения файлов, а затем, когда все куски закончены, вы можете прочитать их все и добавить в один файл и удалить куски.

Обратите внимание, что он работает, назначая изолированную файловую систему для вашего приложения (для данной квоты), и файлы доступны только для этого приложения. Если файлы предназначены для использования вне веб-приложения, вам может понадобиться функция для сохранения файла из файловой системы приложения в его "нормальную" файловую систему. Вы можете сделать что-то подобное, используя метод createObjectURL().

Вы правы в отношении текущего состояния поддержки браузера. Доступен API файловой системы polyfill, основанный на IndexedDB (который более широко поддерживается) в качестве эмулятора эмуляции файловой системы. Я не тестировал polyfill на больших файлах. Вы можете столкнуться с ограничениями по размеру или ограничениями производительности.