Javascript FileSaver在写入大量文件后保存空文件

时间:2012-07-12 21:15:18

标签: javascript file google-chrome filesystems

背景

我正在开发一个基本上可以在客户端生成视频的内部项目,但由于我没有注意到的JavaScript视频编码器,我只是单独导出每个帧。我需要避免上传到服务器;这一切都发生在客户端。

实施

我正在使用此FileSaver.js(更具体地说,Chrome的webkit FileSystem API)来保存HTML5画布生成的大量PNG。我将Chrome设置为自动下载到特定文件夹,因此当我点击“保存”时,它会起飞并保存每秒20张图像。这完全符合我的目的。

如果我可以使用JSZip将所有这些帧压缩到一个文件中,然后再将其提供给客户端进行保存,我会这么做,但我还没试过,因为浏览器根本没有足够的内存生成~8000个640x480 PNG,然后压缩它们。

问题

问题是在一定数量的图像之后,每个下载的文件都是空的。 Chrome甚至开始在下载栏中告诉我该文件是0字节。在具有相同导出设置的同一项目上重复,空保存将在完全相同的时间开始。例如,对于一个项目,我可以在扼流圈之前保存前5494帧。 (我知道这是一个非常大的数字,但我无法帮助。)我尝试在保存之间设置10毫秒的延迟,但这没有任何影响。我没有尝试过更大的延迟,因为导出需要很长时间。

我检查了blob.size,它永远不会为零。我怀疑它超过了一些配额,但没有错误抛出;它只是默默地无法写入沙箱或将文件复制到用户指定的位置。

问题

如何检测这些空保存?防止他们?有一个更好的方法吗?我刚搞砸了吗?


编辑:实际上,在调试FileSaver.js后,我意识到它甚至没有使用webkitRequestFileSystem;当它到达时它会返回:

if (can_use_save_link) {
    object_url = get_object_url(blob);
    save_link.href = object_url;
    save_link.download = name;
    if (click(save_link)) {
        filesaver.readyState = filesaver.DONE;
        dispatch_all();
        return;
    }
}

因此,看起来它甚至没有使用FileSystem API,因此我不知道如何在存储空满之前清空它。


编辑2:我尝试将“if(can_use_save_link)”块移动到“writer.onwriteend”函数内部,并将其更改为:

if (can_use_save_link) {
    save_link.href = file.toURL();
    save_link.download = name;
    click(save_link);
}else{
    target_view.location.href = file.toURL();
}

结果是我能够保存所有8260个文件(总共大约1.5GB),因为它现在使用带有配额的存储。之前,文件没有显示在HTML5文件系统中,因为我假设如果anchor元素支持'download'属性,则不需要将它们放在那里。

我还能够注释掉将“.download”附加到文件名的代码,并且我必须提供一个空的匿名函数作为“file.remove()”的两个实例的参数。

2 个答案:

答案 0 :(得分:0)

使用JSZip,如果禁用压缩(这是默认设置),它将不会使用太多内存。要手动禁用压缩,请务必在调用compression: "STORE"时传递zip.generate()

答案 1 :(得分:0)

我最终修改了FileSaver.js(参见原帖中的“EDIT 2”)。