javascript FileReader-如何以块的形式解析长文件?

时间:2018-09-14 13:55:18

标签: javascript

最初,我是在这里加载的,因此like this

export function сonvertFilesToByteArray(e) {
  const MAX_FILE_SIZE = 1024 * 1024 * 50; // 50MB
  const files = Object.keys(e.target.files);
  const asyncReadFile = eachFile =>
    new Promise((resolve, reject) => {
      if (e.target.files[eachFile].size > MAX_FILE_SIZE) {
        return reject([{ message: `File ${e.target.files[eachFile].name} too large` }]);
      }
      const reader = new FileReader();
      const targetFileInfo = {
        contentType: e.target.files[eachFile].type,
        filename: e.target.files[eachFile].name,
      };
      reader.readAsArrayBuffer(e.target.files[eachFile]);
      reader.onload = () => {
        resolve({ ...targetFileInfo, body: Array.from(new Uint8Array(reader.result)) });
      };
      reader.onerror = error => reject(error);
    });

  return Promise.all(files.map(asyncReadFile));
}

在常量文件中,我定义了文件中的文件数量,并对每个文件应用了函数。

然后我在组件中获取文件

handleFileUpload = (e) => {
    сonvertFilesToByteArray(e)
      .then((result) => {
        runInAction(() => {
          this.files = [
            ...this.files,
            ...result,
          ];
        });
      })
      .catch(err => runInAction(() => {
        this.errors = [...this.errors, err[0].message];
      }));
  }

放入this.files,最后我的this.files看起来像[{contentType: 'plain/text', filename: 'blabla', body: [123, 456, 23, ...] }]

在[123,456,23 ...]那里是我的ArrayBuffer

但是,尽管我使用Promise.all,但在这种方法下,当加载重量大于2MB的文件时,页面被冻结,无法以任何方式与她进行互动(但是我可以滚动)。除了将每个文件分成多个块的实现之外,没有人想到纠正这种情况。 好的,我尝试重写代码:With chunks

export function сonvertFilesToByteArray(e) {
  const MAX_FILE_SIZE = 1024 * 1024 * 50; // 50MB
  const files = Object.keys(e.target.files);
  const asyncReadFile = eachFile =>
    new Promise((resolve, reject) => {
      if (e.target.files[eachFile].size > MAX_FILE_SIZE) {
        return reject([{ message: `File ${e.target.files[eachFile].name} too large` }]);
      }
      const file = e.target.files[eachFile];
      let offset = 0;
      console.log(offset, 'offset', file.size, 'size');
      const defaultChunkSize = 64 * 1024; // bytes
      const fileReader = new FileReader();
      const blob = file.slice(offset, offset + defaultChunkSize);
      const isEndOfFile = () => offset >= file.size;
      const testEndOfFile = () => {
        if (isEndOfFile()) {
          console.log('Done reading file');
        }
      };
      fileReader.readAsArrayBuffer(blob);
      fileReader.onloadend = (event) => {
        const target = (event.target);
        if (target.error == null) {
          const result = target.result;
          offset += result.length;
          testEndOfFile();
          console.log(result, 'result');
          resolve(result);
        } else {
          reject(target.error);
        }
      };
    });

  return Promise.all(files.map(asyncReadFile));
}

在这里,我收到文件并将其分割。但是问题在于,如果文件多于一个大块,那么我应该一次又一次地将他与他们在一起。但是在我的情况下如何做到呢?我完全无法理解...

请帮助我:)要批量读取文件并将其作为ArrayBuffer接收,有什么必要?

0 个答案:

没有答案