缓冲区和 TypedArray
¥Buffers and TypedArrays
Buffer 实例也是 JavaScript Uint8Array 和 TypedArray 实例。所有 TypedArray 方法都可用于 Buffer。但是,Buffer API 和 TypedArray API 之间存在细微的不兼容。
¥Buffer instances are also JavaScript Uint8Array and TypedArray
instances. All TypedArray methods are available on Buffers. There are,
however, subtle incompatibilities between the Buffer API and the
TypedArray API.
特别是:
¥In particular:
-
TypedArray.prototype.slice()创建TypedArray部分的副本,而Buffer.prototype.slice()在现有Buffer上创建视图而不进行复制。这种行为可能会有意外,并且仅存在于旧版兼容性中。TypedArray.prototype.subarray()可用于在Buffer和其他TypedArray上实现Buffer.prototype.slice()的行为,应优先使用。¥While
TypedArray.prototype.slice()creates a copy of part of theTypedArray,Buffer.prototype.slice()creates a view over the existingBufferwithout copying. This behavior can be surprising, and only exists for legacy compatibility.TypedArray.prototype.subarray()can be used to achieve the behavior ofBuffer.prototype.slice()on bothBuffers and otherTypedArrays and should be preferred. -
buf.toString()与其对应的TypedArray不兼容。¥
buf.toString()is incompatible with itsTypedArrayequivalent. -
多种方法,例如
buf.indexOf(),支持额外的参数。¥A number of methods, e.g.
buf.indexOf(), support additional arguments.
有两种方式可以从 Buffer 创建新的 TypedArray 实例:
¥There are two ways to create new TypedArray instances from a Buffer:
-
将
Buffer传递给TypedArray构造函数将复制Buffer内容,解释为整数数组,而不是目标类型的字节序列。¥Passing a
Bufferto aTypedArrayconstructor will copy theBuffers contents, interpreted as an array of integers, and not as a byte sequence of the target type.
import { Buffer } from 'node:buffer';
const buf = Buffer.from([1, 2, 3, 4]);
const uint32array = new Uint32Array(buf);
console.log(uint32array);
// Prints: Uint32Array(4) [ 1, 2, 3, 4 ]const { Buffer } = require('node:buffer');
const buf = Buffer.from([1, 2, 3, 4]);
const uint32array = new Uint32Array(buf);
console.log(uint32array);
// Prints: Uint32Array(4) [ 1, 2, 3, 4 ]-
传递
ArrayBuffer底层的Buffer将创建一个与Buffer共享其内存的TypedArray。¥Passing the
Buffers underlyingArrayBufferwill create aTypedArraythat shares its memory with theBuffer.
import { Buffer } from 'node:buffer';
const buf = Buffer.from('hello', 'utf16le');
const uint16array = new Uint16Array(
buf.buffer,
buf.byteOffset,
buf.length / Uint16Array.BYTES_PER_ELEMENT);
console.log(uint16array);
// Prints: Uint16Array(5) [ 104, 101, 108, 108, 111 ]const { Buffer } = require('node:buffer');
const buf = Buffer.from('hello', 'utf16le');
const uint16array = new Uint16Array(
buf.buffer,
buf.byteOffset,
buf.length / Uint16Array.BYTES_PER_ELEMENT);
console.log(uint16array);
// Prints: Uint16Array(5) [ 104, 101, 108, 108, 111 ]通过以相同的方式使用 TypedArray 对象的 .buffer 属性,可以创建与 TypedArray 实例共享相同分配内存的新 Buffer。Buffer.from() 在这种情况下表现得像 new Uint8Array()。
¥It is possible to create a new Buffer that shares the same allocated
memory as a TypedArray instance by using the TypedArray object's
.buffer property in the same way. Buffer.from()
behaves like new Uint8Array() in this context.
import { Buffer } from 'node:buffer';
const arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
// Copies the contents of `arr`.
const buf1 = Buffer.from(arr);
// Shares memory with `arr`.
const buf2 = Buffer.from(arr.buffer);
console.log(buf1);
// Prints: <Buffer 88 a0>
console.log(buf2);
// Prints: <Buffer 88 13 a0 0f>
arr[1] = 6000;
console.log(buf1);
// Prints: <Buffer 88 a0>
console.log(buf2);
// Prints: <Buffer 88 13 70 17>const { Buffer } = require('node:buffer');
const arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
// Copies the contents of `arr`.
const buf1 = Buffer.from(arr);
// Shares memory with `arr`.
const buf2 = Buffer.from(arr.buffer);
console.log(buf1);
// Prints: <Buffer 88 a0>
console.log(buf2);
// Prints: <Buffer 88 13 a0 0f>
arr[1] = 6000;
console.log(buf1);
// Prints: <Buffer 88 a0>
console.log(buf2);
// Prints: <Buffer 88 13 70 17>使用 TypedArray 的 .buffer 创建 Buffer 时,可以通过传入 byteOffset 和 length 参数仅使用底层 ArrayBuffer 的一部分。
¥When creating a Buffer using a TypedArray's .buffer, it is
possible to use only a portion of the underlying ArrayBuffer by passing in
byteOffset and length parameters.
import { Buffer } from 'node:buffer';
const arr = new Uint16Array(20);
const buf = Buffer.from(arr.buffer, 0, 16);
console.log(buf.length);
// Prints: 16const { Buffer } = require('node:buffer');
const arr = new Uint16Array(20);
const buf = Buffer.from(arr.buffer, 0, 16);
console.log(buf.length);
// Prints: 16Buffer.from() 和 TypedArray.from() 具有不同的签名和实现。具体来说,TypedArray 变体接受第二个参数,该参数是在类型化数组的每个元素上调用的映射函数:
¥The Buffer.from() and TypedArray.from() have different signatures and
implementations. Specifically, the TypedArray variants accept a second
argument that is a mapping function that is invoked on every element of the
typed array:
TypedArray.from(source[, mapFn[, thisArg]])
但是,Buffer.from() 方法不支持使用映射函数:
¥The Buffer.from() method, however, does not support the use of a mapping
function: