загрузить файл на стороне клиента по частям

Я использую WebRTC для отправки файла подключенному узлу, и я отправляю файл частями. Однако у меня возникли проблемы с выяснением, как заставить однорангового узла сохранять / загружать файл по мере его потоковой передачи, фрагмент за фрагментом.

Все примеры, которые я нашел в Интернете, рекомендуют делать что-то вроде этого:

// sender
dataConnection.send({
   'file': file
});

// receiver
dataConnection.on('data', function(fileData) {

    var dataView = new Uint8Array(fileData);
    var dataBlob = new Blob([dataView]);
    var url = window.URL.createObjectURL(dataBlob);

    // create <a>
    var link = document.createElement('a');
    link.href = url;
    link.download = fileName;
    document.body.appendChild(link);

    // trigger the download file dialog
    link.click();
}

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

Я пытаюсь сделать что-то вроде этого:

// sender
for (var i = 0; i < fileSize; i += chunkSize) {

    var fileReader = new FileReader();

    // read next chunk
    var blob = file.slice(start, end);
    ...
    fileReader.onload = function(e) {
        ...
        dataConnection.send({ 'blob': blob });
    }
    fileReader.readAsArrayBuffer(blob);
}

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

http://bloggeek.me/send-file-webrtc-data-api

... описано в разделе «Шаг 6: Загрузка в обычную ФС». Однако этот подход берет все фрагменты по мере их поступления, сохраняет их в памяти, затем создает большой UInt8Array в памяти, а затем позволяет получателю загрузить файл. Это очень много памяти и реально ограничено парой сотен МБ, поэтому не масштабируется.

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


person Hristo    schedule 16.05.2014    source источник
comment
Я не думаю, что это возможно, по крайней мере, с обычным javascript, поскольку нет возможности писать в blob после его создания. Однако вы можете сохранить его в файловой системе localStorage, но только Chrome поддерживает его, и спецификации устарели с месяца, потому что ни один другой браузер не адаптировал его. Это должно предотвратить переполнение памяти, но вам необходимо знать размер всего отправляемого файла перед созданием хранилища.   -  person MarijnS95    schedule 16.05.2014
comment
Я использую WebRTC только для Chrome, так что ничего страшного. Вы можете привести пример того, как localstorage будет работать, или ссылку на несколько примеров?   -  person Hristo    schedule 16.05.2014
comment
@ MarijnS95 , поскольку нет возможности записать в большой двоичный объект после того, как он был создан Можно записать в Blob или, точнее, создать новый Blob, используя байты из существующего Blob, используя Blob.prototype.slice()   -  person guest271314    schedule 25.09.2016
comment
@ guest271314 Действительно возможно создать Blob, который представляет собой конкатенацию других Blob (new Blob([blobA, blobB, blobC])), вам даже не нужно .slice() для этого (если, конечно, вы не имели в виду использование этой функции на стороне отправителя). Однако это не отвечает на вопрос; запрашивающий ищет способ сохранить фрагменты на диск по мере их поступления, вместо того, чтобы где-то их накапливать (например, эти Blob 'уловки') перед загрузкой всего файла через веб-браузер (используя Хотя Blobs, вероятно, лучше, чем UInt8Array).   -  person MarijnS95    schedule 25.09.2016
comment
@ MarijnS95 См. github.com/jimmywarting/StreamSaver.js.   -  person guest271314    schedule 25.09.2016
comment
@ guest271314 Я как раз читал этот код и собирался опубликовать точно такую ​​же ссылку, кажется, что на этот вопрос наконец-то есть верный ответ примерно через два года.   -  person MarijnS95    schedule 25.09.2016
comment
@ MarijnS95 кажется, что на этот вопрос наконец-то есть верный ответ примерно через два года. Хороший кандидат на канонический вопрос / ответ?   -  person guest271314    schedule 25.09.2016


Ответы (1)


ОБНОВЛЕНИЕ

Streams API: https://streams.spec.whatwg.org

https://jakearchibald.com/2016/streams-ftw


К сожалению, из того, что я исследовал, нет возможности открыть диалоговое окно сохранения / загрузки файла и сохранить / загрузить файл в «потоковом» режиме.

Подход, который я выберу, - использовать FileSystem API . К сожалению, это полностью не поддерживается всеми браузерами:

... и маловероятно, что многие браузеры примут этот API :(

  • # P7 #
    # P8 #
person Hristo    schedule 05.06.2014
comment
См. JavaScript: запись для загрузки потока - person guest271314; 26.09.2016
comment
См. stackoverflow.com/questions/39959467/ - person guest271314; 07.11.2016