缓冲区和 TypedArray
【Buffers and TypedArrays】
Buffer 实例也是 JavaScript 的 <Uint8Array> 和 <TypedArray> 实例。所有 <TypedArray> 方法在 Buffer 上都可用。然而,Buffer API 与 <TypedArray> API 之间存在一些细微的不兼容性。
特别是:
【In particular:】
- 当
TypedArray.prototype.slice()创建TypedArray部分内容的副本时,Buffer.prototype.slice()则是在现有Buffer上创建一个视图,而不进行复制。这个行为可能令人惊讶,并且仅为了兼容旧版本而存在。TypedArray.prototype.subarray()可以用于在Buffer和其他TypedArray上实现Buffer.prototype.slice()的行为,并且应当优先使用。 buf.toString()与其TypedArray等效方法不兼容。- 一些方法,例如
buf.indexOf(),支持额外的参数。
有两种方法可以从 Buffer 创建新的 <TypedArray> 实例:
【There are two ways to create new <TypedArray> instances from a Buffer:】
- 将
Buffer传递给 <TypedArray> 构造函数会复制Buffer的内容,将其解释为整数数组,而不是目标类型的字节序列。
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 ]- 传递
Buffer的底层 <ArrayBuffer> 将创建一个与Buffer共享内存的 <TypedArray>。
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:】
Buffer.from() 方法不支持使用映射函数:
【The Buffer.from() method, however, does not support the use of a mapping
function:】