Skip to content

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() 会从中切分,提升性能。