如何使用 JavaScript 操作二进制数据?请解释 ArrayBuffer、TypedArray 和 DataView 的作用和用法。

推荐答案

JavaScript 中操作二进制数据主要依赖于 ArrayBufferTypedArrayDataView 这三个核心对象:

  • ArrayBuffer:表示一个原始的、固定长度的内存区域(缓冲区)。它本身不能直接读写数据,仅作为一块原始内存的容器。你可以把它看作是一块连续的字节数组,但你无法直接通过索引访问。

  • TypedArray:是一组视图,允许以特定的数据类型(如 Int8ArrayUint16ArrayFloat32Array 等)来读取和写入 ArrayBuffer 中的数据。它们提供了类型化的数组视图,可以方便地以不同的数据格式解释同一块内存。

  • DataView:提供了更灵活的、字节级别的读写访问。它允许你指定从 ArrayBuffer 中读取和写入数据的起始位置和数据类型,这在处理不同类型数据混合排列的二进制数据时非常有用。

总的来说,ArrayBuffer 提供原始内存,TypedArray 提供类型化的数组视图,而 DataView 提供灵活的字节级访问。这三者协同工作,使得 JavaScript 可以有效地处理二进制数据。

本题详细解读

ArrayBuffer

ArrayBuffer 是一个不可直接操作的原始二进制数据缓冲区。它仅仅是一段连续的内存空间,长度在创建时确定并且不可更改。你不能直接通过类似数组下标的方式来读写 ArrayBuffer 中的内容。

用途:

  • 作为其他二进制数据视图的基础。
  • 在需要处理原始二进制数据时,先分配一段 ArrayBuffer,然后再通过 TypedArrayDataView 来操作它。

常用属性和方法:

  • byteLength: 返回 ArrayBuffer 的字节长度。
  • slice(begin, end): 创建一个新的 ArrayBuffer,包含原 ArrayBuffer 中指定范围的字节。
  • transfer(newByteLength): 创建一个新的 ArrayBuffer,同时将原有 ArrayBuffer 上的数据复制到新数组中,并且可以改变数组的长度

创建 ArrayBuffer:

TypedArray

TypedArray 提供了一组类型化的数组视图,允许你以特定的数据类型(如整数、浮点数等)来操作 ArrayBuffer 中的数据。每一个 TypedArray 都对应着一种特定的数据类型,例如:

  • Int8Array:8 位有符号整数
  • Uint8Array:8 位无符号整数
  • Int16Array:16 位有符号整数
  • Uint16Array:16 位无符号整数
  • Int32Array:32 位有符号整数
  • Uint32Array:32 位无符号整数
  • Float32Array:32 位浮点数
  • Float64Array:64 位浮点数

用途:

  • 方便地以特定的数据类型来读写 ArrayBuffer 中的数据。
  • 在处理需要特定数据类型的二进制数据(例如图像数据、音频数据等)时非常有用。

创建 TypedArray:

用法:

DataView

DataView 提供了更灵活的、字节级别的读写访问方式。它允许你指定从 ArrayBuffer 中的哪个字节开始,以哪种数据类型来读写数据,并且可以指定字节序(大端或小端)。

用途:

  • 在处理不同数据类型混合排列的二进制数据时非常有用。
  • 在需要控制字节序时(例如,网络协议中常用的字节序转换)。
  • 在需要从 ArrayBuffer 的任意位置读取指定长度的数据时。

创建 DataView:

常用方法:

  • getInt8(byteOffset)getUint8(byteOffset)
  • getInt16(byteOffset, littleEndian)getUint16(byteOffset, littleEndian)
  • getInt32(byteOffset, littleEndian)getUint32(byteOffset, littleEndian)
  • getFloat32(byteOffset, littleEndian)
  • getFloat64(byteOffset, littleEndian)
  • setInt8(byteOffset, value)setUint8(byteOffset, value)
  • setInt16(byteOffset, value, littleEndian)setUint16(byteOffset, value, littleEndian)
  • setInt32(byteOffset, value, littleEndian)setUint32(byteOffset, value, littleEndian)
  • setFloat32(byteOffset, value, littleEndian)
  • setFloat64(byteOffset, value, littleEndian)

其中,byteOffset 指定字节偏移量,littleEndian 指定是否使用小端字节序(默认为 false,即大端字节序)。

用法:

纠错
反馈