如何访问由Blob创建的ArrayBuffer的索引?

9

我不认为自己是一名程序员,所以在这个网站上搜索了很多问题的答案。然而,我无法解决这个问题。

我正在尝试使用JavaScript(实际上是我目前唯一能尝试的语言)上传文件并将其二进制数据加载到ArrayBuffer中进行编辑。我使用FileSaver.js和Blob.js来提高兼容性。用户选择文件后,加载文件。当加载开始时,FileReader使用readAsArrayBuffer将文件加载到ArrayBuffer中。我目前已将其设置为通过警报检查ArrayBuffer的内容,但最终将删除该警报并直接处理数据。

如果我去掉索引,警报会知道它正在显示一个ArrayBuffer,但是每当我选择一个索引(例如[0]),它就告诉我它未定义。如何将文件数据加载到ArrayBuffer中?它将如何分割?最好每个索引都有1个字节。

function loadButtonPressed() {
    var loadedFile = document.getElementById('loadFile').files;
    var testFile = loadedFile[0];
    var reader = new FileReader();
    reader.onloadend = function(evt) {
        if (evt.target.readyState == FileReader.DONE) {
            alert(String(reader.result[0]));
        }
    };
    reader.readAsArrayBuffer(testFile);
}
2个回答

13
要访问ArrayBuffer的数据,您需要从中创建一个视图。
这可以通过两种方式完成: TypedArrays 这些类似于数组的对象,您的ArrayBuffer的每个字节将以所选的TypedArray类型表示。请注意,这将使用系统的字节顺序。

var buf = new TextEncoder().encode('Hello world').buffer;
console.log(buf);
// create an Uint8 view
var view = new Uint8Array(buf);
console.log(view);
// now you can iterate and modify your arrayBuffer from this view.
view[0] = 23;

console.log(new Uint8Array(buf)[0]);

DataView

这种方法速度较慢,但可以获得更多选项来获取和设置ArrayBuffer中的数据。例如,您可以设置字节序,无需检查缓冲区的byteLength即可获取Int32值等。

var buf = new TextEncoder().encode('Hello world').buffer;
console.log(buf);
// create a dataView
var view = new DataView(buf);
console.log(view.getUint8(0));
// now you can iterate and modify your arrayBuffer from this view.
view.setUint8(0, 23);

console.log(new Uint8Array(buf)[0]);

注意:这两种方法都会直接修改ArrayBuffer的数据,而且不会克隆其数据。

感谢您的深入解释! - Floydman

6

缓冲区只是一系列无意义的字节。JS没有提供直接操作缓冲区的方法。要查看缓冲区,需要使用视图,该视图定义了缓冲区的解释方式——可以是类型化数组或DataView对象。尝试如下操作:

// ...
let buffer = reader.result;
let view = Int8Array(buffer);
console.log(view[0]);

或者是这样的:
// ...
let buffer = reader.result;
console.log(new DataView(buffer).getInt8(0))

1
请记住,readAsArrayBuffer是异步的并且返回void。视图必须在处理程序内部(或之后)创建。 - user1693593
谢谢!知道答案如此简单真是太好了。 - Floydman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接