深入理解 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 引入了 ArrayBuffer 、TypedArray 和 DataView。

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

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

1. 创建 ArrayBuffer

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

2. ArrayBuffer 的特点

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

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

TypedArray 是一组视图,允许以特定的数据类型(如 Int8、Float32)读写 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 文件中提取图像元数据。
  • 自定义数据结构:处理混合数据类型的二进制流。 例如,解析游戏存档中的复杂数据结构。
相关推荐
橙光成长34 分钟前
PDF离线工具箱深度解析:4MB纯前端单文件,40+功能全本地运行,文件绝不上传
前端·pdf·1024程序员节
小poop7 小时前
CSS 基础与实战:从入门到精通网页美化
前端
考研保研资料分享8 小时前
中国人民大学英语笔译保研面经:五校考核、视译口译与择校复盘
面试
Csvn9 小时前
运行时性能
前端
Never_every999 小时前
位图转矢量工具哪个好?实测抠抠图AI位图转矢量工具
大数据·前端
paopaokaka_luck10 小时前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节
古希腊掌管代码的神THU10 小时前
为什么DPO中chosen/rejected概率同时下降?
人工智能·深度学习·机器学习·自然语言处理·面试
空中湖10 小时前
用 React 写数据大屏:为什么我不建议用图表库
前端·react.js·前端框架
欣欣之王来了12 小时前
原始HTML插值:v-html指令的使用与安全风险
前端·学习·架构·项目·vue3教程
IT_陈寒12 小时前
Redis的LRU淘汰策略坑了我一整天
前端·人工智能·后端