【问题标题】:Save client generated data as file in JavaScript in chunks将客户端生成的数据分块保存为 JavaScript 中的文件
【发布时间】:2013-10-10 05:14:09
【问题描述】:

我正在使用 webRTC 开发 FileShare 应用程序。我想用 JavaScript/HTML 实现客户端。该代码应在客户端浏览器上运行。 通过 webRTC 下载时我需要保存它们。这些文件可能非常大,在将它们作为文件保存到磁盘之前,我无法完全下载它们并将它们保存在数组或 blob 中。

是否有任何 API 可以让我在收到文件时将文件分块保存?

到目前为止,我已经找到了 DownloadifyFileSave.jshtml5 FileWriterApi。 虽然前两个没有分块并且需要我在保存之前先将完整的文件下载到内存中,但 FileWriterAPI 在大多数浏览器上不可用。

【问题讨论】:

  • 对于合理大小的文件,我的第一直觉是将每个块存储在自己的Blob 中,最后将它们全部连接到一个大Blob 中(使用新的构造函数)并使用createObjectURL 保存最终的Blob。 IIRC,JS Blobs 在必要时存储到磁盘,所以除非文件真的很大(或者我真的错了;)),它不应该太可怕?
  • @JordanGray 可能是个好主意 - 我认为下载的块需要在浏览器会话之间持续下载,但如果不是,这可能是最干净的想法(如果浏览器确实实现了持久化blob 在需要时归档)。

标签: javascript html flash firefox webrtc


【解决方案1】:

正如@jordan-gray 建议的那样,将块保存在 blob 中并将它们加入更大的 blob 可能是一种解决方案,如果:

  • 不需要持久化块(即关闭浏览器将删除所有块)
  • 只有用户将文件保存到自己的文件系统中才能持久保存该文件。 Web 应用程序在关闭后将无法访问该文件,除非用户再次授予对已保存文件的访问权限。
  • 可能,如果文件大小不是太大(您必须进行基准测试才能发现)。对于总计 1GB 的块,Chrome 对我来说表现得非常好。

我创建了一个simple test for using blobs as chunks。您可以使用不同的大小和块编号参数:

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 应该支持您的需求。您可以使用它将块写入单独的文件,然后当所有块完成后,您可以将它们全部读取并将它们附加到单个文件中,然后删除块。

请注意,它通过为您的应用程序(对于给定的配额)分配沙盒文件系统来工作,并且文件只能由该应用程序访问。如果文件打算在 Web 应用程序之外使用,您可能需要使用该函数将文件从应用程序文件系统保存到他的“正常”文件系统。您可以使用createObjectURL() 方法执行类似的操作。

您对浏览器支持的当前状态是正确的。 A Filesystem API polyfill 可用,它基于IndexedDB(得到更广泛的支持)作为文件系统仿真后端。我没有在大文件上测试 polyfill。您可能会遇到大小限制或性能限制。

【讨论】:

  • 是的,这就是我的想法。根据我对规范的理解,它应该能够很好地扩展,必要时将块保存到底层存储。 :)
  • 看起来这仍然是先保存到内存(currentChunk == totalChunks) ,然后再保存到磁盘,对吗?
  • 不,将 new Blob() 视为返回指向磁盘上对象的指针。 developer.mozilla.org/en/docs/Web/API/Blob
  • @AmitayDobo 它如何显示第一个块的下载过程,我希望它显示浏览器的下载行为。能做到吗?
【解决方案2】:

你检查https://github.com/Peer5/Sharefest了吗?它应该满足您的要求

【讨论】:

猜你喜欢
  • 2015-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-04
  • 1970-01-01
  • 2015-08-30
相关资源
最近更新 更多