一、计算机中的数据与存储单位
在计算机系统中,数据的基本存储单位是 比特(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 文件中提取图像元数据。
- 自定义数据结构:处理混合数据类型的二进制流。 例如,解析游戏存档中的复杂数据结构。