Webrtc datachannels:在大文件传输期间将数据保存在文件中
Webrtc datachannels: saving data in file during transfer of big files
我正在使用 WebRTC 数据通道构建文件传输服务。
对于 30 Mb 左右的较小文件,它运行得很好。现在在接收端我只是将文件数据保存在内存中,当所有数据传输完毕后我保存文件。
有点像这样:
//On the recieving side
var dataArray = [];
var dcOnMessage= function(event){
dataArray .push(event.data);
if(bytesToRecieve == 0)
{
var blob = new Blob(dataArray ,{type: incFileDesc.type});
reader.onload = function (event) {
saveToDisk(event.target.result,incFileDesc.name);
}
reader.readAsDataURL(blob);
}
}
var saveToDisk = function(fileUrl, fileName) {
var save = document.createElement('a');
save.href = fileUrl;
save.target = '_blank';
save.download = fileName || fileUrl;
var event = document.createEvent('Event');
event.initEvent('click', true, true);
save.dispatchEvent(event);
(window.URL || window.webkitURL).revokeObjectURL(save.href);
}
所以我想把数据保存在磁盘上的一个文件中,然后直接写入那个文件。但是我该怎么做呢?
由于缺少将数据附加到 blob 的方法(请参阅从未在所有浏览器中实现的 BlobBuilder API),目前您所做的是最好的方法。一旦 Chrome(就像 Mozilla 已经做的那样)支持发送 blobs over the datachannel.
,这可能会改变
filetransfer sample 适用于最大 1 GB 的文件。
我认为您不能将文件保存在磁盘上(出于安全原因),但您可以将其作为 BLOB 保存到 indexedDB。 IndexedDB 现在得到广泛支持(参见 http://caniuse.com/#search=indexeddb),适用于本地大型对象存储。
有关 API 的更多详细信息,请参阅 https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API。
下面是一个在 IndexedDB 中保存 BLOB 的例子:https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
恐怕当前的标准化 APIs 不会轻易允许这样做(请参阅 Philipp 的回复)。最接近的方法是将每个保存为 blob/etc in localstorage/indexeddb,然后使用 Blob 构造函数从一组 blob 构建最终文件。它仍然会有大约 2 倍文件大小的临时内存占用。或者只保留内存中的每个 blob,直到构建最终的 Blob 并保存到磁盘(仍然是内存命中,但逐渐增加,直到构建最终的 blob 时达到 2 倍)。当最终文件的大小达到可用 RAM 的大小范围时,这些可能会开始出现问题。
在 Firefox 中直接传输单个大 Blob->Firefox 现在可以使用已弃用的低级分块机制在没有 SCTP ndata 支持(尚不可用)的情况下工作;它避免了内存命中的 2x 部分。
Chrome 中有一个非标准的 API,它主要可以完成追加到文件的部分,上次我检查过。这一直是 WebAPI 用户持续讨论的领域;可能是时候再次戳他们了。
我正在使用 WebRTC 数据通道构建文件传输服务。
对于 30 Mb 左右的较小文件,它运行得很好。现在在接收端我只是将文件数据保存在内存中,当所有数据传输完毕后我保存文件。
有点像这样:
//On the recieving side
var dataArray = [];
var dcOnMessage= function(event){
dataArray .push(event.data);
if(bytesToRecieve == 0)
{
var blob = new Blob(dataArray ,{type: incFileDesc.type});
reader.onload = function (event) {
saveToDisk(event.target.result,incFileDesc.name);
}
reader.readAsDataURL(blob);
}
}
var saveToDisk = function(fileUrl, fileName) {
var save = document.createElement('a');
save.href = fileUrl;
save.target = '_blank';
save.download = fileName || fileUrl;
var event = document.createEvent('Event');
event.initEvent('click', true, true);
save.dispatchEvent(event);
(window.URL || window.webkitURL).revokeObjectURL(save.href);
}
所以我想把数据保存在磁盘上的一个文件中,然后直接写入那个文件。但是我该怎么做呢?
由于缺少将数据附加到 blob 的方法(请参阅从未在所有浏览器中实现的 BlobBuilder API),目前您所做的是最好的方法。一旦 Chrome(就像 Mozilla 已经做的那样)支持发送 blobs over the datachannel.
,这可能会改变filetransfer sample 适用于最大 1 GB 的文件。
我认为您不能将文件保存在磁盘上(出于安全原因),但您可以将其作为 BLOB 保存到 indexedDB。 IndexedDB 现在得到广泛支持(参见 http://caniuse.com/#search=indexeddb),适用于本地大型对象存储。 有关 API 的更多详细信息,请参阅 https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API。 下面是一个在 IndexedDB 中保存 BLOB 的例子:https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
恐怕当前的标准化 APIs 不会轻易允许这样做(请参阅 Philipp 的回复)。最接近的方法是将每个保存为 blob/etc in localstorage/indexeddb,然后使用 Blob 构造函数从一组 blob 构建最终文件。它仍然会有大约 2 倍文件大小的临时内存占用。或者只保留内存中的每个 blob,直到构建最终的 Blob 并保存到磁盘(仍然是内存命中,但逐渐增加,直到构建最终的 blob 时达到 2 倍)。当最终文件的大小达到可用 RAM 的大小范围时,这些可能会开始出现问题。
在 Firefox 中直接传输单个大 Blob->Firefox 现在可以使用已弃用的低级分块机制在没有 SCTP ndata 支持(尚不可用)的情况下工作;它避免了内存命中的 2x 部分。
Chrome 中有一个非标准的 API,它主要可以完成追加到文件的部分,上次我检查过。这一直是 WebAPI 用户持续讨论的领域;可能是时候再次戳他们了。