Buffer 深入
Buffer 是 Node.js 处理二进制数据的核心类,全局可用,无需 require。
为什么需要 Buffer?
JavaScript 原本设计用于浏览器,处理 Unicode 字符串很 OK,但处理 TCP 流、文件 I/O、图像/视频等二进制数据很弱。Buffer 填补了这个空缺。
创建 Buffer
js
// 方式一:alloc(安全,自动清零)
const buf1 = Buffer.alloc(10) // <Buffer 00 00 00 00 00 00 00 00 00 00>
// 方式二:allocUnsafe(更快,但不初始化,可能含旧数据)
const buf2 = Buffer.allocUnsafe(10) // <Buffer ?? ?? ?? ...> 内存碎片内容
// 方式三:from
const buf3 = Buffer.from('hello') // <Buffer 68 65 6c 6c 6f>
const buf4 = Buffer.from([0x68, 0x65]) // <Buffer 68 65>
const buf5 = Buffer.from(buf1) // 拷贝另一个 Buffer
allocUnsafe更快但不安全,只在立即填充全部数据时使用。
读写数据
js
const buf = Buffer.alloc(4)
buf[0] = 0x68 // 直接索引写入
buf.writeUInt32BE(255, 0) // 大端序写 32 位无符号整数
buf.readUInt32BE(0) // 大端序读
buf.writeInt16LE(100, 0) // 小端序写 16 位有符号整数
buf.readInt16LE(0) // 小端序读常用方法
js
// 转换
buf.toString('utf-8') // Buffer → 字符串
buf.toString('hex') // Buffer → 十六进制字符串
buf.toJSON() // → { type: 'Buffer', data: [104,101,...] }
// 判读
Buffer.isBuffer(obj) // 是否为 Buffer
Buffer.byteLength('你好') // 8 (utf8 中文每字 3 字节)
// 拼接
Buffer.concat([buf1, buf2, buf3])
// 对比
buf1.equals(buf2) // 内容是否相同
Buffer.compare(buf1, buf2) // 排序对比
// 切片(共享内存!修改切片会影响原 Buffer)
const slice = buf.subarray(0, 5) // 从 0 到 5
// 填充
buf.fill(0) // 全部填充为 0字节序:大端 vs 小端
js
const buf = Buffer.alloc(4)
buf.writeUInt32BE(0x12345678, 0) // [12, 34, 56, 78] 高字节在前
buf.writeUInt32LE(0x12345678, 0) // [78, 56, 34, 12] 低字节在前| 大端 (BE) | 小端 (LE) | |
|---|---|---|
| 高字节 | 存低地址 | 存高地址 |
| 网络字节序 | TCP/IP (网络序) | x86 CPU (主机序) |
| 常用场景 | 网络传输 | 本地计算 |
Buffer 与 TypedArray
Buffer 是 Uint8Array 的子类(Node.js 特有扩展),可与 TypedArray 互操作:
js
const buf = Buffer.from([1, 2, 3, 4])
const uint32 = new Uint32Array(buf.buffer) // 共享同一块内存
uint32[0] = 0x12345678
console.log(buf) // Buffer 内容同步变化内存池
Node.js 使用内存池(8KB slab)预分配小 Buffer,Buffer.alloc() 会从中切分,提升性能。