在网页中,我必须读取文件的一小部分,对于许多(1500-12000)小文件来说,每个文件的大小约为1 Mb。收集所需信息后,将其推回到服务器上。
我的问题:我使用FileReader API,垃圾收集无法正常工作,并且内存消耗激增。
代码如下:
function extract_information_from_files(input_files) {
//some dummy implementation
for (var i = 0; i < input_files.length; ++i) {
(function dummy_function(file) {
var reader = new FileReader();
reader.onload = function () {
//convert to Uint8Array because used library expects this
var array_buffer = new Uint8Array(reader.result);
//do some fancy stuff with the library (very small subset of data is kept)
//finish
//function call ends, expect garbage collect to start cleaning.
//even explicit dereferencing does not work
};
reader.readAsArrayBuffer(file);
})(input_files[i]);
}
Run Code Online (Sandbox Code Playgroud)
}
一些说明:
当结合使用FileReader和https://gildas-lormeau.github.io/zip.js/时,最后一个奇怪的细节(为完整性而发布),我在将文件推送到zip存档之前读取了文件,垃圾收集才可以正常工作。
所有这些说明似乎都指向我无法使用FileReader,因此请告诉我如何使用。
该问题可能与执行顺序有关。在您的for循环中,您正在读取所有带有reader.readAsArrayBuffer(file). onload该代码将在为读者运行任何代码之前运行。根据浏览器的实现,这可能意味着浏览器在调用FileReader任何文件之前加载整个文件(或者简单地为整个文件预分配缓冲区) 。onload
尝试像队列一样处理文件,看看是否有区别。就像是:
function extract_information_from_files(input_files) {
var reader = new FileReader();
function process_one() {
var single_file = input_files.pop();
if (single_file === undefined) {
return;
}
(function dummy_function(file) {
//var reader = new FileReader();
reader.onload = function () {
// do your stuff
// process next at the end
process_one();
};
reader.readAsArrayBuffer(file);
})(single_file);
}
process_one();
}
extract_information_from_files(file_array_1);
// uncomment next line to process another file array in parallel
// extract_information_from_files(file_array_2);
Run Code Online (Sandbox Code Playgroud)
编辑:浏览器似乎希望您重用FileReaders。我编辑了代码以重用单个阅读器,并测试(在 Chrome 中)内存使用量仍仅限于您读取的最大文件。