在javascript中,我想阅读所有选定的用户文件。
我使用文件夹选择输入字段来获取文件,从导航器变量中获取可用内核的数量,甚至是gb中的RAM。
我正在使用队列算法,因此我根据可用核心创建了一个Web worker任务。
然后我遍历每个工作人员,并从文件列表中切掉batch
大小,然后交给工人。
每次工作人员完成时,它会从文件列表中获取另一个大小为batch
的片段,直到没有剩余文件,并且所有工作者都已完成。
我无法确定要使用的batch
大小值。它可以修复或基于某些公式。
我发现如果我有77个文件,批量大小为16可以正常工作,如果我有151324,那么批量大小为300就可以了。但我不想选择一个可以扼杀记忆的批量大小,但同时也要加快速度。
我也从每个文件中读取最多75千字节。
此外,每个文件都有一个size属性。如果我做任何预先分类,它会有所作为吗?
有谁知道怎么做?
由于
答案 0 :(得分:0)
必须对此进行测试,但是通过使用URL#createObjectURL,您理论上可以创建指向磁盘上文件的直接指针,可供您的工作人员使用,而无需从主线程复制任何数据。
这意味着您的批量大小可能只是files.length / numberOfWorkers
。
<强> A rough proof of concept: 强>
(作为一个小提琴,因为StackSnippet的null起源iframe使这个技巧变得不可能......)
在工人中:
self.onmessage = e => {
Promise.all(
e.data.map(async (url)=>
fetch(url).then(r=>r.blob())
// here you can do whatever you have to do with the file
.then(file => new FileReaderSync()
.readAsText(file.slice(0,75))
)
)
)
.then(console.log)
.catch(console.error);
};
</script>
在主页面中:
// workers is an Array containing your WebWorkers
inp.onchange = e => {
const urls = [...inp.files]
.map(file => URL.createObjectURL(file));
const batchSize = Math.ceil(urls.length / (navigator.hardwareConcurrency));
workers.forEach((worker, i) => {
worker.postMessage(urls.slice(i*batchSize, i*batchSize + batchSize));
});
};