当前位置: 首页 > 知识库问答 >
问题:

如何追加字节,多字节和缓冲区到ArrayBuffer在javascript?

翟宏放
2023-03-14

Javascript ArrayBuffer或TypedArrays没有任何类型的appendByte()、appendBytes()或appendBuffer()方法。所以,如果我想一次填充一个数组缓冲一个值,我该怎么做呢?

var firstVal = 0xAB;              // 1 byte
var secondVal = 0x3D7F            // 2 bytes
var anotherUint8Array = someArr;

var buffer = new ArrayBuffer();   // I don't know the length yet
var bufferArr = new UInt8Array(buffer);

// following methods do not exist. What are the alternatives for each??
bufferArr.appendByte(firstVal);
bufferArr.appendBytes(secondVal);
bufferArr.appendBuffer(anotherUint8Array);

共有2个答案

韦胜泫
2023-03-14

Paul的答案允许您将一个TypedArray连接到现有的TypedArray。在ES6中,可以使用以下函数连接多个TypeDarray:

function concatenate(resultConstructor, ...arrays) {
    let totalLength = 0;
    for (const arr of arrays) {
        totalLength += arr.length;
    }
    const result = new resultConstructor(totalLength);
    let offset = 0;
    for (const arr of arrays) {
        result.set(arr, offset);
        offset += arr.length;
    }
    return result;
}

const ta = concatenate(Uint8Array,
    Uint8Array.of(1, 2), Uint8Array.of(3, 4));
console.log(ta); // Uint8Array [1, 2, 3, 4]
console.log(ta.buffer.byteLength); // 4

要追加一个新字节是:

const byte = 3;
concatenate(Uint8Array, Uint8Array.of(1, 2), Uint8Array.of(byte));

方法可在ExploringJS中找到。

晋承嗣
2023-03-14

可以使用新的ArrayBuffer创建新的TypedArray,但不能更改现有缓冲区的大小

function concatTypedArrays(a, b) { // a, b TypedArray of same type
    var c = new (a.constructor)(a.length + b.length);
    c.set(a, 0);
    c.set(b, a.length);
    return c;
}

现在我能做什么

var a = new Uint8Array(2),
    b = new Uint8Array(3);
a[0] = 1; a[1] = 2;
b[0] = 3; b[1] = 4;
concatTypedArrays(a, b); // [1, 2, 3, 4, 0] Uint8Array length 5

如果你想使用不同的类型,通过Uint8Array,因为最小的单位是一个字节,即。

function concatBuffers(a, b) {
    return concatTypedArrays(
        new Uint8Array(a.buffer || a), 
        new Uint8Array(b.buffer || b)
    ).buffer;
}

这意味着。长度将按预期工作,您现在可以将其转换为您选择的类型化数组(请确保它是一个类型,将接受缓冲区的

从这里,您现在可以实现任何连接数据的方法,例如。

function concatBytes(ui8a, byte) {
    var b = new Uint8Array(1);
    b[0] = byte;
    return concatTypedArrays(ui8a, b);
}

var u8 = new Uint8Array(0);
u8 = concatBytes(u8, 0x80); // [128]

 类似资料:
  • 用这种方式将字节缓冲符转换为字符串是否正确, 我问这个问题的原因是,这看起来太简单了,而像Java这样的其他方法:将字符串转换成字节缓冲符和相关问题看起来更复杂。

  • 问题内容: 有没有一种方法可以使用BufferedReader读取ByteBuffer而不必先将其转换为String?我想读取相当大的ByteBuffer作为文本行,并且出于性能方面的考虑,我想避免将其写入磁盘。在ByteBuffer上调用toString不起作用,因为生成的String太大(它抛出java.lang.OutOfMemoryError:Java堆空间)。我本来以为API中会有一些东

  • 我目前正在处理一些小的endian二进制数据,我已经到了一个尴尬的地步,需要将奇数字节转换成整数值。 现在使用类,我能够很好地使用函数读取int和long,它们分别读取4和8个字节。 然而,在本例中,我需要读取三个字节,并将它们转换为int。我尝试过使用(2字节1字节),但我认为这不是正确的方法。 我猜我需要对字节进行位移位才能得到正确的int值,但我总是对位移位感到困惑。 此外,我还以为字节缓冲

  • 我试图读取名为使用。JS代码: 但是运行代码会产生这个错误: 这个错误对我来说毫无意义。由返回的缓冲区怎么可能不是的实例?将替换为或也不能解决此问题。我目前正在使用节点。JS版本14.17.6(LTS)。

  • 我正在尝试更新Android BluetoothChat示例的代码,以使用Protobuf进行更结构化的数据交换。我还需要byte[]数组字段来发送任意数据,如图像字节数组,但在尝试编译时。proto文件,我得到以下错误。 协议文件/蓝牙消息。proto:8:18:应为字段名。 下面是我的. proto文件。 stackoverflow上的其他几个帖子提到byte[]可以用作文件,下面的页面也说了

  • 我想使用swig从C附加到Javabyte[]。诀窍是在不调用GetByteArrayElements的情况下执行此操作,因为如果无法固定byte[],这将生成byte[]的副本。 没有swig,我们可以使用SetByteArrayArea轻松做到这一点-直接将字节数写入byte[]。swg的问题是: > 执行实际工作的代码在. cpp中-例如读取文件的内容并将其放入字符串fileContents