2

我正在使用HTML5 FileReader readAsArrayBuffer()方法将文件读入内存。根据规范(上面链接):

在处理读取时,随着来自 blob 的数据变得可用, 用户代理应该将任务排队以使用部分 Blob 数据作为 ArrayBuffer [TypedArrays] 对象更新结果,该对象包含读取完成之前读取的字节,以伴随进度事件的触发. 获取时,结果属性返回部分 Blob 数据,表示当前加载的字节数(作为总数的一部分)[ProgressEvents],作为 ArrayBuffer [TypedArrays] 对象;用户代理在处理这个读取方法时必须至少返回一个这样的 ArrayBuffer [TypedArrays]。最后一个返回值是在读取完成时。

但是,在我测试过的浏览器(Firefox、Chrome 和 Opera)中,该reader.result属性似乎并没有持续更新。例如:

var reader = new FileReader(), pos = 0;

reader.addEventListener("progress", function(event){
    console.log(reader.result);
    var content = new Uint8Array(reader.result, pos, event.loaded);
    pos = event.loaded;

    // do stuff with the content down here
});

document.getElementById("fileInput").addEventListener("change", function(event){
    reader.readAsArrayBuffer(event.target.files[0]);
});

其中有一个 IDfileInput和 type的 HTMLInputElement file。When a sufficiently large file is chosen and the callback runs, here is what happens on the console (this example is from Chrome):

null
Uncaught TypeError: Type error

我相信出现 TypeError 是因为数组视图 Uint8Array 无法从 ArrayBuffer 读取块,因为 ArrayBuffer 为空。

奇怪的是,如果文件很大但不是太大,一些进度事件实际上会成功运行。

您如何可靠地实现 FileReader 的 ArrayBuffer 以在“进度”事件时为您提供所需的数据?

4

1 回答 1

1

我猜你可以在文件加载后读取 ArrayBuffer 。以下功能也可以处理大文件。希望能帮助到你,

function onfilechange(evt) {
var reader = new FileReader(); 
reader.onload = function(evt) {
  var chars  = new Uint8Array(evt.target.result);
  var CHUNK_SIZE = 0x8000; 
  var index = 0;
  var length = chars.length;
  var result = '';
  var slice;
  while (index < length) {
    slice = chars.subarray(index, Math.min(index + CHUNK_SIZE, length)); 
    result += String.fromCharCode.apply(null, slice);
    index += CHUNK_SIZE;
  }
  // Here you have file content as Binary String in result var
};
reader.readAsArrayBuffer(evt.target.files[0]);
}
于 2014-09-03T20:17:15.347 回答