缓冲区和 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 Buffer
s. 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 existingBuffer
without 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 bothBuffer
s and otherTypedArray
s and should be preferred. -
buf.toString()
与其对应的TypedArray
不兼容。¥
buf.toString()
is incompatible with itsTypedArray
equivalent. -
多种方法,例如
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
Buffer
to a <TypedArray> constructor will copy theBuffer
s 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
Buffer
s underlying <ArrayBuffer> will create a <TypedArray> that 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: 16
const { Buffer } = require('node:buffer');
const arr = new Uint16Array(20);
const buf = Buffer.from(arr.buffer, 0, 16);
console.log(buf.length);
// Prints: 16
Buffer.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: