调整ArrayBuffer的大小

don*_*aka 9 javascript arrays

如果我想创建一个arraybuffer,我写道: var buff = new ArrayBuffer(size)

但是如何调整现有缓冲区的大小呢?我的意思是,在缓冲区的末尾添加更多的字节.

小智 12

ArrayBuffer本身没有设置.有set对TypedArray虽然.使用这样:

var oldBuffer = new ArrayBuffer(20);

var newBuffer = new ArrayBuffer(40);
new Uint8Array(newBuffer).set(oldBuffer);
Run Code Online (Sandbox Code Playgroud)

  • 我不知道为什么,但在我的 Firefox 65 中提供的示例不起作用。`new Uint8Array(newBuffer).set(oldBuffer)` newBuffer 包含零之后。为了解决这个问题,我必须向 set() 提供类型化数组:`new Uint8Array(newBuffer).set(new Uint8Array(oldBuffer))`——在这种情况下,它按预期工作。 (4认同)
  • 给出的例子效果很好。该代码不需要指向“Uint8Array”的指针,因为它仅使用它来访问“set”函数 (2认同)

Den*_*ret 6

你不能.

来自MDN:

ArrayBuffer是一种数据类型,用于表示通用的 固定长度二进制数据缓冲区.

我不知道你尝试做什么,但显然你不会使用它们如何使用它们.

这个页面是学习如何在JavaScript中使用类型化数组的一个很好的起点.

  • 那么怎么可能创建一个以旧元素开始的新元素呢? (2认同)

Jon*_*den 6

您正在寻找的是“设置”方法。创建新的更大数组后,只需调用set函数并复制旧内容即可。


Art*_*yer 6

这样做的方法是ArrayBuffer.transfer(oldBuffer, newByteLength),例如:

var buffA = new ArrayBuffer(30);
var buffB = ArrayBuffer.transfer(buffA, 40);

// buffA is now an empty array buffer (`buffA.byteLength === 0`)
// whereas buffB is a new buffer that starts with a's contents
// and ends with 10 bytes that are 0s.

// Much faster than manually copying. You could even just do:

var buffA = new ArrayBuffer(30);
buffA = ArrayBuffer.transfer(buffA, 40);

// Or as a prototype method

ArrayBuffer.prototype.resize = function(newByteLength) {
    return ArrayBuffer.transfer(this, newByteLength);
}

var buffA = new ArrayBuffer(30);
buffA = buffA.resize(40);
Run Code Online (Sandbox Code Playgroud)

但是(截至2017年10月),浏览器支持为0%(甚至不支持Node.js),甚至还没有起草。


在此功能可用之前,您可以使用页面上给定的polyfill,一次可复制8个字节,因此对于大型数组来说相对较快(尽管它不会清空给定的数组,这是不可能的)。

这是使用TypeArray.prototype.set而不是for循环的修改版本:

if (!ArrayBuffer.transfer) {
  ArrayBuffer.transfer = function(oldBuffer, newByteLength) {
    var srcBuffer = Object(oldBuffer);
    var destBuffer = new ArrayBuffer(newByteLength);
    if (!(srcBuffer instanceof ArrayBuffer) || !(destBuffer instanceof ArrayBuffer)) {
      throw new TypeError('Source and destination must be ArrayBuffer instances');
    }
    var copylen = Math.min(srcBuffer.byteLength, destBuffer.byteLength);

    /* Copy 8 bytes at a time */
    var length = Math.trunc(copylen / 64);
    (new Float64Array(destBuffer, 0, length))
      .set(new Float64Array(srcBuffer, 0, length));

    /* Copy the remaining 0 to 7 bytes, 1 byte at a time */
    var offset = length * 64;
    length = copylen - offset;
    (new Uint8Array(srcBuffer, offset, length))
      .set(new Uint8Array(destBuffer, offset, length));

    return destBuffer;
  };
}
Run Code Online (Sandbox Code Playgroud)

  • 该提案已被撤回,因此该答案已失效 (3认同)

pro*_*ard -10

var buff = new ArrayBuffer(32);
buff[31] = 43;
var newBuff = new ArrayBuffer(buff.byteLength*2);

for (var i=0;i<buff.byteLength;i++){
    newBuff[i] = buff[i];
}

buff = newBuff;
Run Code Online (Sandbox Code Playgroud)

我已经用 C++ 这样做了。只需创建一个更大的数组并将内容复制过来,然后返回更大的数组并将其设置为原始数组。

  • 我很困惑为什么这个被接受。**“ArrayBuffer”的内容不能用“[]”_直接_访问,而只能通过_Views_(例如_Typed arrays_和“DataView”)访问。**代码处理的是属性,而不是它们的内容。您会看到内容:`console.log(new Uint8Array(buf));`。 (9认同)
  • 在 JS 中,应该使用 TypedArray.prototype.set() 在数组之间进行复制,正如 Jon Lennart Aasenden 所建议的那样。 (6认同)