在网页中,我必须阅读文件的一小部分,这对于许多(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]);
}
}
一些评论:
最后一个奇怪的细节(发布完整性),当使用FileReader结合https://gildas-lormeau.github.io/zip.js/时,我在将文件推送到zip存档之前读取文件,垃圾收集工作正常。
所有这些评论似乎都指向我无法使用FileReader,所以请告诉我如何。
答案 0 :(得分:2)
问题可能与执行顺序有关。在for
循环中,您正在阅读reader.readAsArrayBuffer(file)
的所有文件。此代码将在为读者运行任何onload
之前运行。根据{{1}}的浏览器实现,这可能意味着浏览器在调用任何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);
。我编辑了代码以重用单个阅读器并测试(在chrome中)内存使用量仅限于您阅读的最大文件。