深入理解 ArrayBuffer、TypedArray 和 DataView

一、计算机中的数据与存储单位

在计算机系统中,数据的基本存储单位是 比特(bit) ,它表示二进制中的 0 或 1。8 个比特构成 1 个 字节(Byte) ,这是计算机处理中最小的可寻址单位。

常见的存储单位如下:

单位 大小
1 bit 0 或 1
1 Byte 8 bit
1 KB 1024 Byte
1 MB 1024 KB
1 GB 1024 MB
1 TB 1024 GB

在 JavaScript 中,数据通常以对象、字符串、数字等高级抽象形式存在,无法直接操作底层的二进制数据。因此,为了高效处理原始二进制数据,HTML5 引入了 ArrayBufferTypedArrayDataView

二、ArrayBuffer ------ 原始二进制数据的容器

ArrayBuffer 是一种用于表示固定长度的二进制数据缓冲区,主要用于存储和传递原始数据。它本质上是对底层内存的抽象,提供了一块连续的内存空间,不能直接读写,需要通过视图(TypedArrayDataView)来操作。

1. 创建 ArrayBuffer

arduino 复制代码
// 创建一个 16 字节的 ArrayBuffer
const buffer = new ArrayBuffer(16);
console.log(buffer.byteLength); // 16

2. ArrayBuffer 的特点

  • 固定长度:创建时必须指定长度,且不可调整。
  • 不可直接操作 :需要借助 TypedArrayDataView
  • 适用场景 :WebGL、文件操作(如 FileReader)、网络数据(如 WebSocket)。

三、TypedArray ------ 操作特定类型的二进制数据

TypedArray 是一组视图,允许以特定的数据类型(如 Int8Float32)读写 ArrayBuffer。它们的主要作用是高效地处理二进制数据,并能更好地与底层硬件交互。

1. 常见的 TypedArray 类型

类型 每元素字节数 数据范围 特点
Int8Array 1 -128 ~ 127 有符号 8 位整数,支持负数
Uint8Array 1 0 ~ 255 无符号 8 位整数,仅支持正数
Int16Array 2 -32,768 ~ 32,767 有符号 16 位整数,支持更大范围
Uint16Array 2 0 ~ 65,535 无符号 16 位整数,适合正整数扩展
Int32Array 4 -2^31 ~ 2^31-1 有符号 32 位整数,适用于大整数
Uint32Array 4 0 ~ 2^32-1 无符号 32 位整数,适合更大正数
Float32Array 4 32 位 IEEE-754 浮点数 单精度浮点数,适用于小数精确存储
Float64Array 8 64 位 IEEE-754 浮点数 双精度浮点数,适用于更高精度计算

2. 创建 TypedArray

javascript 复制代码
// 创建一个包含 8 个元素的 Int16Array,底层使用 ArrayBuffer
const int16View = new Int16Array(8);

// 赋值与访问
int16View[0] = 256;
console.log(int16View[0]); // 256

// 通过已有的 ArrayBuffer 创建视图
const buffer = new ArrayBuffer(16);
const int32View = new Int32Array(buffer);
console.log(int32View.length); // 4 (16 / 4 = 4)

3. TypedArray 的特性

  • 类型固定 :每个 TypedArray 只能存储一种特定类型的数据。
  • 性能优化:更接近底层,适合大量数据处理,如音视频、图像数据。
  • 自动对齐:根据数据类型自动按照字节对齐,提升读写性能。

4. TypedArray 的应用场景

  • WebGL :处理 3D 图形中的顶点、颜色数据。 例如,使用 Float32Array 存储顶点坐标并传递给 GPU 进行渲染。
  • 音视频处理 :解析音频数据、生成波形图。 例如,使用 Uint8Array 处理 PCM 音频数据,生成实时波形。
  • 网络数据:解析二进制协议数据,如 WebRTC、WebSocket。 例如,解析自定义二进制数据包,提取多字段信息。
  • 图像操作 :操作像素数据,生成特效或滤镜。 例如,使用 Uint8ClampedArray 操作图像像素,进行灰度转换。

四、DataView ------ 灵活操作二进制数据

DataView 是一种更通用的视图,允许按字节精确地操作 ArrayBuffer。与 TypedArray 不同,DataView 不限制数据类型,适用于多种数据类型混合的场景。

1. 创建 DataView

arduino 复制代码
const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);

// 写入数据
view.setInt8(0, 127);
view.setFloat32(4, 3.14);

// 读取数据
console.log(view.getInt8(0)); // 127
console.log(view.getFloat32(4)); // 3.14

2. DataView 的特性

  • 灵活性:可以按需读写任何数据类型。
  • 字节序控制 :支持 大端 (Big-Endian)与 小端(Little-Endian)。
  • 适用场景:解析复杂的二进制文件(如图片、音频格式)。
  • 额外开销 :每次读写需要手动计算偏移和类型,导致性能略低于 TypedArray

3. DataView 的应用场景

  • 解析多种数据类型:如网络协议头、复杂二进制格式。 例如,解析 TCP/IP 数据包的头部字段。
  • 文件解析:解析图片、音频、视频文件(如 PNG、MP3、MP4)。 例如,从 PNG 文件中提取图像元数据。
  • 自定义数据结构:处理混合数据类型的二进制流。 例如,解析游戏存档中的复杂数据结构。
相关推荐
Channing Lewis12 分钟前
API 返回的PDF是一串字符,如何转换为PDF文档
前端·python·pdf
海盗强16 分钟前
css3有哪些新属性
前端·css·css3
Cutey91622 分钟前
前端如何实现菜单的权限控制(RBAC)
前端·javascript·设计模式
yannick_liu24 分钟前
不引入第三方库,绘制圆环
前端
无名之逆25 分钟前
告别死锁!Hyperlane:Rust 异步 Web 框架的终极解决方案
服务器·开发语言·前端·网络·http·rust
公谨27 分钟前
MasterGo AI 生成设计图及代码
前端·人工智能
不会Android潘潘27 分钟前
HTTP2.0之Header 入门版、面试版 一看就懂
前端
Java中文社群28 分钟前
拿下美团实习~
java·后端·面试
心态与习惯29 分钟前
c++ 中的可变参数模板与折叠表达式
前端·c++·可变参数模板·折叠表达式
高端章鱼哥29 分钟前
Java的volatile和sychronized底层实现
前端