Skip to main content
Bun 实现了多种用于在 JavaScript 中处理二进制数据的数据类型和实用工具,其中大多数符合 Web 标准。Bun 特有的 API 会特别标注。 本速查表同时也是目录;点击左列中的类即可跳转到对应章节。

ArrayBuffer 和视图

直到 ECMAScript v5(2009 年)引入了一系列机制之前,JavaScript 都没有语言原生的方式来存储和操作二进制数据。其中最基础的构建块是 ArrayBuffer,一种表示内存中字节序列的数据结构。
尽管名称中包含“数组”(array),但它并不是数组,也不支持你可能期待的任何数组方法和运算符。你无法直接从 ArrayBuffer 中读取或写入值;你能做的只有检查其大小,以及从中创建“切片”。
要读取或写入数据,你需要一个“视图”:一种_封装_ ArrayBuffer 实例,并允许你读取和操作底层数据的类。视图有两种类型:_类型化数组_和 DataView

DataView

DataView 类是一个底层接口,用来读取和操作 ArrayBuffer 中的数据。 以下代码创建一个 DataView,并将第一个字节设置为 3。
接下来,在字节偏移量 1 处写入一个 Uint16。这需要两个字节。值 513 等于 2 * 256 + 1;用字节表示就是 00000010 00000001
底层 ArrayBuffer 的前三个字节现在都有值。尽管第二个和第三个字节是通过 setUint16() 写入的,你仍然可以使用 getUint8() 读取每个组成字节。
如果写入的值所需空间大于底层 ArrayBuffer 的可用空间,就会抛出错误。以下代码尝试在字节偏移量 0 处写入一个 Float64(需要 8 个字节),但该缓冲区的长度只有 4 个字节。
DataView 支持以下方法:

TypedArray

类型化数组是一组类,提供类似数组的接口,用于访问 ArrayBuffer 中的数据。与 DataView 可以在某个偏移量写入不同大小的数字不同,TypedArray 将底层字节解释为固定大小数字的数组。
通常会通过它们共同的超类 TypedArray 来统称这一系列类。这个类对于 JavaScript 来说是 内部的;你无法直接创建它的实例,并且 TypedArray 未定义在全局作用域中。可以将它视为一个 interface 或抽象类。
类型化数组类,以及每种类型如何解释 ArrayBuffer 中的字节: 下面的表展示了用不同类型化数组类查看 ArrayBuffer 字节时的字节解释方式: 下面的表展示了不同类型化数组类如何解释 ArrayBuffer 中的相同字节。 从已有的 ArrayBuffer 创建类型化数组:
从同一个 ArrayBuffer 实例化 Uint32Array 会抛出错误。
一个 Uint32 值需要四个字节(32 位)。由于 ArrayBuffer 的长度为 10 个字节,因此无法将其内容整齐地划分为每组 4 个字节的数据块。 要解决此问题,请在 ArrayBuffer 的特定“切片”上创建类型化数组。下面的 Uint32Array 只“查看”底层 ArrayBuffer 的前 8 个字节:byteOffset0length2,表示该数组所包含的 Uint32 值的数量。
你不需要先创建 ArrayBuffer 实例;可以直接将长度传递给类型化数组构造函数:
类型化数组也可以直接从数字数组或另一个类型化数组创建:
类型化数组提供与普通数组相同的方法,但有少数例外。例如,pushpop 不可用,因为它们需要调整底层 ArrayBuffer 的大小。
有关类型化数组属性和方法的更多信息,请参阅 MDN 文档

Uint8Array

Uint8Array 是 JavaScript 中最常见的类型化数组。它表示经典的“字节数组”:由一系列介于 0 到 255 之间的 8 位无符号整数组成。 在 Bun 中,它提供了在字节数组与其 base64 或十六进制字符串表示形式之间进行转换的方法。
它是 TextEncoder#encode 的返回值,也是 TextDecoder#decode 的输入类型。这两个实用工具类用于在字符串与各种二进制编码之间进行转换,其中最重要的是 "utf-8"

Buffer

Bun 实现了 Node.js 的 Buffer,这是一个在 JavaScript 标准中引入类型化数组之前用于操作二进制数据的 API。现在它已重新实现为 Uint8Array 子类,提供多种方法,包括数组方法和类似 DataView 的方法。
参见 Node.js 文档

Blob

Blob 是一种通常用于表示文件的 Web API。它最初源自浏览器(不同于属于 JavaScript 本身的 ArrayBuffer),但 Node.js 和 Bun 也支持它。 你很少会直接创建 Blob 实例;它们通常来自外部来源(例如浏览器中的 <input type="file"> 元素)或某个库。不过,你可以使用一个或多个字符串或二进制“Blob 部分”创建 Blob
这些部分可以是 stringArrayBufferTypedArrayDataView 或其他 Blob 实例。这些部分会按照给定的顺序进行拼接。
以各种格式异步读取 Blob 的内容。

BunFile

BunFileBlob 的子类,表示磁盘上延迟加载的文件。与 File 一样,它添加了 namelastModified 属性。与 File 不同,它不要求将文件加载到内存中。

File

FileBlob 的子类,添加了 namelastModified 属性。在浏览器中,它通常用于表示通过 <input type="file"> 元素上传的文件。Node.js 和 Bun 都实现了 File
请参阅 MDN 文档

流让你能够处理二进制数据,而无需一次性将所有数据加载到内存中。它们通常用于读取和写入文件、发送和接收网络请求,以及处理大量数据。 Bun 实现了 Web API 中的 ReadableStreamWritableStream
Bun 还实现了 node:stream 模块,包括 Readable, WritableDuplex。完整文档请参见 Node.js 文档。
要创建可读流:
使用 for await 逐块读取流。
有关 Bun 中流的更多信息,请参见

格式转换

使用本节作为将一种二进制格式转换为另一种格式的参考。

ArrayBuffer

由于 ArrayBuffer 存储着其他二进制结构(如 TypedArray)所依赖的数据,以下代码片段并不是将 ArrayBuffer 转换 为另一种格式。相反,它们使用底层数据_创建_一个新实例。

转为 TypedArray

转为 DataView

转为 Buffer

转为字符串

按 UTF-8 编码:

转为数字数组(number[]

转为 Blob

转为 ReadableStream

以下示例创建一个 ReadableStream,并将整个 ArrayBuffer 作为一个 chunk 入队。
要分块流式传输 ArrayBuffer,使用 Uint8Array 视图并逐块入队。

TypedArray

转为 ArrayBuffer

buffer 属性是底层的 ArrayBufferTypedArray 可以是该缓冲区某个_切片_的视图,因此两者的大小可能不同。

转为 DataView

要创建一个覆盖与 TypedArray 相同字节范围的 DataView

转为 Buffer

转为字符串

按 UTF-8 编码:

转为数字数组(number[]

转为 Blob

转为 ReadableStream

分块流式传输 ArrayBuffer,将类型化数组划分为多块,分别入队。

DataView

转为 ArrayBuffer

转为 TypedArray

仅当 DataViewbyteLength 是类型化数组元素字节大小的倍数时有效。

转为 Buffer

转为字符串

按 UTF-8 编码:

转为数字数组(number[]

转为 Blob

转为 ReadableStream

分块流式传输 ArrayBuffer,将 DataView 划分为多块,逐块入队。

Buffer

转为 ArrayBuffer

转为 TypedArray

转为 DataView

转为字符串

按 UTF-8:
按 base64:
按十六进制:

转为数字数组(number[]

转为 Blob

转为 ReadableStream

分块流式传输 ArrayBuffer,将 Buffer 划分多块,逐块入队。

Blob

转为 ArrayBuffer

转为 TypedArray

转为 DataView

转为 Buffer

转为字符串

按 UTF-8:

转为数字数组(number[]

转为 ReadableStream

ReadableStream

Response 是将 ReadableStream 转换为其他格式时常用的中间类型。
但这种方式较为冗长,并且会增加不必要的开销。Bun 为将 ReadableStream 转换为各种二进制格式实现了经过优化的便捷函数。

转为 ArrayBuffer

转为 Uint8Array

转为 TypedArray

转为 DataView

转为 Buffer

转为字符串

按 UTF-8:

转为数字数组(number[]

Bun 提供了用于解析 ReadableStream 为其块数组的工具。每个块可能是字符串、类型化数组或 ArrayBuffer

转为 Blob

转为 ReadableStream

要将一个 ReadableStream 分割为两个可独立消费的流: