只读取 Javascript 中文件的第一个块

Read only the first chunk of a file in Javascript

我们有一个基于浏览器的界面,用户可以在其中选择要上传的文件。

选择文件后,它会加载到 FileReader 对象中,内容会加载到内存中并通过调用 FileReader.readAsText() 进行验证。

这适用于 50MB 的文件(需要 2-3 秒)。 但是,当您的文件大小达到 200MB 时,甚至在 20 分钟后,文件仍未完成读取并且处理器保持在 100% 的利用率。

我认为这是由于内存耗尽造成的,因为整个文件都被加载到一个变量中。

有没有什么方法可以分块加载文件的内容,而不是将整个文件加载到一个巨大的、吸内存的怪物中?

我们只需要验证文件的前 1KB 左右,所以我们需要做的就是读取第一个有效块,然后完成。

概念证明,自己测试:

<form>
  <input type="file" /> File
</form>
<script type="text/javascript">
  var input = document.getElementsByTagName('input')[0];
  input.onchange = function(e) {
    var file = input.files[0];
    var reader = new FileReader();
    reader.onload = function() {
      var file_contents = reader.result;
      alert('File Read. Size:' + file_contents.length);
    };
    reader.readAsText(file);
  };
</script>

我会利用 File 实现的 Blob 接口,它的 .stream() 方法 returns a ReadableStream.

async function validateFile(file) {
  const stream = file.stream();
  const reader = stream.getReader();
  let bytesRead = 0;
  let exhausted = false;
  while (bytesRead < 1e3 && !exhausted) {
    const {value, done} = await reader.read();

    // value is a Uint8Array
    bytesRead += value ? value.length : 0;
    exhausted = done;
  }
}