【发布时间】:2014-07-05 07:30:09
【问题描述】:
我正在使用 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 步:下载到常规 FS” 中描述。但是,这种方法会在所有块进入时将它们存储在内存中,然后在内存中构建一个大的UInt8Array,然后让接收者下载文件。这非常占用内存,实际上限制在几百 MB,因此无法扩展。
有没有办法在第一个块进入后打开文件下载对话框,并在块进入时继续写入,以便下载是“流式”下载?
【问题讨论】:
-
我认为这是不可能的,至少对于普通的 javascript 来说是不可能的,因为在 blob 创建后无法写入。但是,您可以将其存储在 localStorage 文件系统中,但只有 chrome 支持它,并且一个月以来不推荐使用规范,因为没有其他浏览器适应它。这应该可以防止内存溢出,但您需要在创建存储之前知道正在发送的总文件的大小。
-
我只在 Chrome 上使用 WebRTC,这样就可以了。您能否举例说明
localstorage的工作原理,或链接到一些示例? -
@MarijnS95 “因为在 blob 创建后无法写入” 可以写入
Blob,或者更确切地说是创建一个新的Blob使用来自现有Blob的字节使用Blob.prototype.slice() -
@guest271314 确实可以创建一个
Blob,它是其他Blobs(new Blob([blobA, blobB, blobC]))的串联,你甚至不需要.slice()(除非你当然,这意味着在发送方使用该功能)。但是,这并不能回答问题;提问者正在寻找一种方法,以便在块进入时将它们保存到 disk,而不是在通过网络浏览器下载整个文件之前将它们累积到某处(例如,这些Blob'tricks') (不过,使用Blobs 可能比使用UInt8Array更好)。 -
@MarijnS95 见github.com/jimmywarting/StreamSaver.js
标签: html blob webrtc fileapi chunking