我正在尝试使用JavaScript中的FileApi
来访问文本文件的前几行。
为了实现这个目标,我从文件开头剪切任意数量的字节,并将blob传递给FileReader
。
对于大型文件,这需要很长时间,尽管我目前的理解是只需要访问文件的前几个字节。
- 在后台是否有一些必须在对文件进行片段操作之前先访问整个文件的实现方式?
- 这取决于FileApi的浏览器实现吗?
我目前已在Chrome和Edge (chromium)中测试过。
Chrome中使用性能开发工具进行分析显示,在reader.onloadend
之前存在很多空闲时间,且内存使用没有增加。不过,这可能是因为FileApi
是在浏览器本身中实现的,因此不会反映在JavaScript性能统计数据中。
我的FileReader实现看起来像这样:
const reader = new FileReader();
reader.onloadend = (evt) => {
if (evt.target.readyState == FileReader.DONE) {
console.log(evt.target.result.toString());
}
};
// Slice first 10240 bytes of the file
var blob = files.item(0).slice(0, 1024 * 10);
// Start reading the sliced blob
reader.readAsBinaryString(blob);
这个方法运作得很好,但正如描述的那样,对于大文件表现不佳。我尝试了10kb、100mb和6gb的文件。似乎直到第一个10kb被记录的时间与文件大小直接相关。
有关于如何提高读取文件开头性能的任何建议吗?
编辑: 使用@BenjaminGruenbaum建议的响应流和DOM流,可悲地不能提高读取性能。
var dest = newWritableStream({
write(str) {
console.log(str);
},
});
var blob = files.item(0).slice(0, 1024 * 10);
(blob.stream ? blob.stream() : newResponse(blob).body)
// Decode the binary-encoded response to string
.pipeThrough(newTextDecoderStream())
.pipeTo(dest)
.then(() => {
console.log('done');
});
Response
和DOM流有帮助吗?我不确定为什么在这里使用readAsBinarySring
很慢,因为在blob上使用.slice
应该只读取您想要的部分 - 但是您所描述的情况表明确实正在等待整个文件。 - Benjamin Gruenbaumnew Blob([await file.arrayBuffer()])
)时会发生什么?浏览器在首次访问文件时必须对其进行“快照”,但我认为通常只使用lastModified字段,尽管对于较大的文件,您的操作系统可能需要更长时间来访问文件的元数据。 - Kaiido