我正在使用 webRTC 开发 FileShare 应用程序。我想用 JavaScript/HTML 实现客户端。该代码应在客户端浏览器上运行。 通过 webRTC 下载时我需要保存它们。这些文件可能非常大,我无法完全下载它们并将它们保存在数组或 blob 中,然后再将它们作为文件保存到磁盘。
是否有任何 API 允许我在收到文件时将文件分块保存?
到目前为止我已经找到了Downloadify,FileSave.js和html5 FileWriterApi。 虽然前两个没有分块,并且要求我在保存之前首先将完整的文件下载到内存中,但 FileWriterAPI 在大多数浏览器上不可用。
正如@jordan-gray所建议的,将块保存在blob中并将它们加入到更大的blob中可能是一个解决方案,如果:
我创建了一个使用 blob 作为块的简单测试。您可以使用不同的大小和块数参数:
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 文件系统 API 应该可以支持您的需求。您可以使用它将块写入单独的文件,然后当所有块完成后,您可以读取它们并将它们附加到单个文件,然后删除块。
请注意,它的工作原理是为您的应用程序分配沙盒文件系统(对于给定的配额),并且这些文件只能由该应用程序访问。如果这些文件要在 Web 应用程序之外使用,您可能需要使用该功能将文件从应用程序文件系统保存到他的“正常”文件系统。您可以使用 createObjectURL() 方法执行类似的操作。
您对浏览器支持当前状态的看法是正确的。 文件系统 API polyfill 可用,它基于 IndexedDB(得到更广泛的支持)作为文件系统模拟后端。我没有在大文件上测试polyfill。您可能会遇到大小限制或性能限制。
您查看https://github.com/Peer5/Sharefest了吗?它应该满足您的要求
while (currentChunk < totalChunks) {
var offset = currentChunk * chunkSize;
var currentFilePart = rr.files.item(0).slice(offset, (offset+chunkSize));
var cFilePart = new FileReader();
var ar1 = new Uint8Array(currentFilePart.arrayBuffer());
for (var i = 0; i < chunkSize; i++)
{
st = ar1[i] ^ bb;
st = ar1[i];
Rajar2[Rajtop] = iii;
Rajtop++;
}
currentChunk++;
iii = iii + currentChunk;
}
{
{
var blob1 = new Blob([Rajar2], {type: "application/octet-stream"});
var fileName = 'a.txt';
var url = window.URL.createObjectURL(blob1);
{
var element = document.createElement('a');
element.style.display = 'none';
element.href = url;
element.download = fileName;
document.body.appendChild(element);
element.click();
}
}
}