开发者问题收集

FileReader() 无法读取大文件

2016-10-30
8823

我使用以下方法在上传图像之前预览它们:

$("#file").change(function() {
  var reader = new FileReader();
  reader.readAsArrayBuffer(this.files[0]);
  var fileName = this.files[0].name;
  var fileType = this.files[0].type;
  alert(fileType)
  reader.onloadend = function() {
    var base64Image = btoa(String.fromCharCode.apply(null, new Uint8Array(this.result)));
    // I show the image now and convert the data to base 64
  }
}

我注意到,当图像很大时,该方法会失败,我无法预览图像。
我不确定问题是由于 base64 转换还是 FileReader 造成的。
是否有任何设置可以增加最大尺寸,或者有任何解决方法?

这是控制台中抛出的错误消息:

Uncaught RangeError: Maximum call stack size exceeded
at FileReader.reader.onloadend

3个回答

您的问题是您使用了 Function.apply ,它会将您的 Typed Array 项转换为 String.fromCharCode 方法的参数。

函数 具有最大参数长度限制

为了避免这种情况,在处理大文件时, 最好的方法是根本不处理它

如果您需要将文件发送到服务器,只需直接发送 Blob,这可以通过 FormData API。

如果您需要显示文件,即在 HTML 媒体元素中,请使用 URL.createObjectURL(yourFile) 方法。

如果您确实需要文件的 dataURI 版本,请使用 reader.readAsDataURL(yourFile) 方法。

Kaiido
2016-10-30

对我有用:

var reader = new FileReader();

reader.onload = function (evt) {
    var binary = '';
    var bytes = new Uint8Array(reader.result);
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }
    console.log(btoa(binary))
}

reader.readAsArrayBuffer(file)
dibrovsd
2019-04-01

如果您使用 FileReader 读取文件,整个文件将被加载到内存中。如果您想处理大文件,这只会导致您的网络浏览器立即崩溃。如果您真的有兴趣将文件作为 Base64 字符串 传递,我建议您添加文件大小限制以防止任何潜在问题。总而言之, FileReader 类的任何方法都不适合此目的,除非您正在处理不大于 100MG 左右的小文件,否则您将遇到问题。

Transcendent
2016-10-30