如何将字节,多字节和缓冲区添加到JavaScript中的ArrayBuffer?
Javascript ArrayBuffer或TypedArrays没有任何类型的appendByte(),appendBytes()或appendBuffer()方法。所以如果我想一次填充一个ArrayBuffer的一个值,我该怎么做?如何将字节,多字节和缓冲区添加到JavaScript中的ArrayBuffer?
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);
您可以创建一个新的TypedArray用新ArrayBuffer,但你不能改变现有的缓冲区的大小
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;
}
这意味着.length
会按预期工作,你现在可以将此转换为您键入的选择阵列(请确保它是会接受缓冲区的.byteLength
虽然A型)
从这里开始,您现在可以实现您喜欢的任何连接数据的方法,例如
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]
感谢@Paul S.如果将这些基本功能作为规范的一部分并在本地实现,本来是不错的,但是您的解决方案非常好。我仍然有一个问题,你将如何附加一个多字节,可以说一个4字节的值给一个类型数组。我们可以循环并为每个单字节多次调用你的'concatBytes'函数,但是它能以更好的方式完成吗? – codneto
@codneto你的多字节如何存储?例如如果你使用整数,你怎么知道'0x3D7F'和'0x00003D7F'之间的区别?是的,我同意应该有一些本地'concat',但我不认为应该有一个本地'push'或_length_改变 - 这不是类型化数组如何工作 –
S,我有一些函数返回4个字节值,我需要添加到缓冲区。我也从流中读取一些字节并追加到缓冲区,有时候基于某些标志我必须读取1,2或4个字节值,所有这些都需要附加到缓冲区。我应该如何完成将这些多字节值附加到缓冲区? – codneto
Paul的答案允许您将一个TypedArray连接到现有的TypedArray。在ES6,你可以用下面的函数来连接多个TypedArrays:
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找到。
它是一个数组,使用数组语法'r [i] = x'例如:https://github.com/rndme/download/blob/master/download.js#L69也查看Uint8Array构造函数的语法: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array#Syntax - 你需要在该阵列缓冲区上的大小,以便能够像那样使用它...... – dandavis
你创建后无法修改缓冲区大小 –