当尝试读取大文件时,Chrome HTML5 FileReader崩溃

5

我有一个表单,允许用户选择一个zip文件上传。 我正在尝试在上传到服务器之前对该zip文件进行客户端验证,因为上传可能需要一些时间,而且我也想节省带宽。

我只需要读取zip中应包含的.csv文件,并验证.csv中引用的其他文件是否存在于zip中。 为此,我尝试使用JSZip

如果存档很小,则效果很好。 如果存档很大(使用约500MB文件进行测试),则Chrome会崩溃。

var  reader = new FileReader();
reader.onload = function (e) {
  console.log("Got here!");
  // Read csv using JSZip, validate zip contents
};
reader.readAsArrayBuffer(file);

我在代码中注释掉了onload回调函数中的所有逻辑,并验证了这些逻辑不会导致崩溃。我发现Chrome在onload回调函数之前就崩溃了。

我已经在FireFox上测试了更大的zip文件,它可以正常工作。


你使用的是哪个版本的Chrome浏览器? - Alon Gubkin
刚刚发现,对于超过1.5GB的文件,FireFox在同一点崩溃。版本号为31.0.1650.63。 - Danny
那很可能是浏览器标签页内存不足了。为什么要在客户端读取这么大的文件呢? - Ray Nicholus
我在处理大的 BLOB 时遇到了同样的错误。我发现这是一个未经记录的 bug,目前没有人对此进行任何处理。 - Michal
FileReaderSync 和 Web Worker - epascarello
@Michal 如果您发现了未记录的错误,请提交错误报告:http://cbrug.com/new - Rob W
1个回答

2

浏览器标签页的空间不足了。

为了处理这样一个大文件,你应该一次加载它的片段

使用File.slice(start, end + 1),将结果读取为ArrayBuffer,处理该块数据,然后确保没有对它的引用,以便进行垃圾回收。

根据你正在处理的数据块,你可能需要设置定时器给予垃圾回收器额外的时间。务必测试所有支持的浏览器,因为有些浏览器可能会强制你设置更长的超时或更小的数据块大小。此外,请记住,在性能较弱的电脑上,垃圾回收可能需要更长的时间。

这是切片的一个好例子。当然,您会按照更大的块来切片。您还可能想结合页面上的下一个例子,以便在包括从缓慢/远程存储中获取块和当前块编号的进度反馈。


链接似乎已经改变,这个页面上没有关于分片加载文件的内容,提前感谢。 - maroof shittu
1
@maroofshittu 真是太疯狂了,https://www.html5rocks.com/en/tutorials/file/dndfiles/#toc-slicing-files 现在重定向到 https://web.dev/read-files/! - Mihail Malostanidis
1
话虽如此,答案可能需要更新,因为新的 Blob.stream() 对于这种用例来说可能比 Blob.slice() 更好! - Mihail Malostanidis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接