4

我需要将 2 个现有 arrayBuffers 的 2 个部分组合成一个新的。

我正在构建一个解析器,数据来自随机大小的数组缓冲区,数据将溢出到一个的末尾,进入另一个的开头。所以我需要创建一个新的输出缓冲区并复制一个缓冲区末尾的一部分和另一个缓冲区开头的一部分。输出将只是一个 Arraybuffer。

从这个演示开始,我打算用一些偏移量制作 Uint8Arrays 然后使用 set,问题是某些组合 throw Invalid typed array length。我不会事先知道每个数组的长度或偏移量。

var buffer1 = new ArrayBuffer(8);
var buffer2 = new ArrayBuffer(8);
var buffer3 = new ArrayBuffer(8);

var uint8_1 = new Uint8Array(buffer1);
var uint8_2 = new Uint8Array(buffer2);
var uint8_3 = new Uint8Array(buffer3);

uint8_1.fill(1);
uint8_2.fill(2);

var uint8_1_slice = new Uint8Array(buffer1 , 0 , 3);
var uint8_2_slice = new Uint8Array(buffer2 , 4, 7);

对于此演示,需要将 buffer3 设置为 1,1,1,1,2,2,2,2。

不能使用切片

4

2 回答 2

3

我见过一些人只使用array.length. 只要数组每个元素只有 1 个字节就可以了。如果其他类型的数组被填满也很好,但在这个例子a2中没有。这就是为什么最好使用byteLengththis 也是 Blob 构造函数连接部件的方式。

// Concatenate a mix of typed arrays
function concatenate(...arrays) {
  // Calculate byteSize from all arrays
  let size = arrays.reduce((a,b) => a + b.byteLength, 0)
  // Allcolate a new buffer
  let result = new Uint8Array(size)

  // Build the new array
  let offset = 0
  for (let arr of arrays) {
    result.set(arr, offset)
    offset += arr.byteLength
  }

  return result
}

// the total length of 1-3 = 5
// the total byteLength of 1-3 = 6
let a1 = Uint8Array.of(1, 2) // [1, 2]
let a2 = Uint16Array.of(3) // [3] just for the fun of it 16 takes up 2 bytes
let a3 = Uint8Array.of(4, 5) // [4, 5]

concatenate(a1, a2, a3) // [1, 2, 3, 0, 4, 5]

/********/
var blob = new Blob([a1, a2, a3])
var res = new Response(blob)
res.arrayBuffer().then(buffer => console.log(new Uint8Array(buffer)))
// [1, 2, 3, 0, 4, 5]
于 2016-10-18T12:39:52.043 回答
1

对于此演示,需要将 buffer3 设置为 1,1,1,1,2,2,2,2。

您可以使用forloop, set uint8_3to uint8_1value if variablen小于uint8_1.byteLength / 2else set uint8_3to value at uint8_2

var len = 8;

var buffer1 = new ArrayBuffer(len);
var buffer2 = new ArrayBuffer(len);
var buffer3 = new ArrayBuffer(len);

var uint8_1 = new Uint8Array(buffer1);
var uint8_2 = new Uint8Array(buffer2);
var uint8_3 = new Uint8Array(buffer3);

uint8_1.fill(1);
uint8_2.fill(2);
// `len` : uint8_1.byteLength / 2 + uint8_2.byteLength / 2
for (var n = 0; n < len; n++) {
  uint8_3[n] = n < len / 2 ? uint8_1[n] : uint8_2[n];
}

console.log(uint8_3);

于 2016-09-15T03:08:50.110 回答