【问题标题】:JavaScript FileReader Slice PerformanceJavaScript FileReader 切片性能
【发布时间】:2022-04-30 15:41:40
【问题描述】:

我正在尝试使用 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 and DOM streams 有帮助吗?我不确定为什么 readAsBinarySring 在这里很慢,因为在 blob 上使用 .slice 应该只读取您想要的部分 - 但是您所描述的表明它确实在等待整个文件。
  • @BenjaminGruenbaum 使用响应和 DOM 流读取文件有效,但遗憾的是并没有提高大文件的读取性能。
  • @BenjaminGruenbaum 我在问题中添加了 DOM Stream 实现。
  • 那么FileReader跟它没有关系?为什么不在问题中说清楚?对我来说,这听起来就像你的操作系统花了所有时间来触摸文件并生成元数据。恐怕没有什么 slice() 可以改变的。至于为什么您的操作系统会花费相对于文件大小的时间,我不知道。可能值得在其他环境中进行测试,包括其他硬盘、其他文件系统等。
  • 在加载文件时读取文件的开头,而不是之后。

标签: javascript blob filereader fileapi


【解决方案1】:

这个怎么样!!

function readFirstBytes(file, n) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      resolve(reader.result);
    };
    reader.onerror = reject;
    reader.readAsArrayBuffer(file.slice(0, n));
  });
}

readFirstBytes('file', 10).then(buffer => {
  console.log(buffer);
});

【讨论】:

  • 这如何提高前N字节的读取性能?您是否使用多种文件大小对其进行了测试?为什么这种方法与我的帖子中描述的方法有什么不同?
猜你喜欢
  • 1970-01-01
  • 2016-07-07
  • 2014-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-20
  • 2021-01-17
相关资源
最近更新 更多