Buffer 是 Node.js 中的一个重要概念,它用于处理二进制数据流。Buffer 类在全局作用域中可用,不需要通过 require 引入。本文将全面介绍 Buffer 的概念、使用方法和最佳实践。
Buffer 是一个类似于数组的对象,但它专门用于存储字节数据。Buffer 的大小在创建时确定,且无法调整。每个元素的取值范围是 0-255(即一个字节)。
// 创建一个长度为 10 字节的 Buffer,用 0 填充
const buf1 = Buffer.alloc(10);
// 创建一个长度为 10 字节的 Buffer,用 1 填充
const buf2 = Buffer.alloc(10, 1);
// 创建一个长度为 10 字节的 Buffer,但不初始化
const buf3 = Buffer.allocUnsafe(10);
注意:allocUnsafe() 方法创建的 Buffer 可能包含旧数据,性能较好但需要谨慎使用。
// 从字符串创建
const buf4 = Buffer.from('Hello World');
// 从数组创建
const buf5 = Buffer.from([1, 2, 3, 4, 5]);
// 从另一个 Buffer 创建
const buf6 = Buffer.from(buf4);
const buf = Buffer.alloc(4);
buf.write('Hey!');
// 转换为字符串
console.log(buf.toString());
// 读取指定位置的字节
console.log(buf[0]); // 输出 ASCII 码值
// 复制 Buffer
const copyBuf = Buffer.alloc(4);
buf.copy(copyBuf);
// 切片操作
const sliceBuf = buf.slice(0, 2);
// 连接 Buffer
const combinedBuf = Buffer.concat([buf1, buf2]);
Buffer 支持多种字符编码:
const buf = Buffer.from('Hello', 'utf8');
console.log(buf.toString('base64')); // 转换为 base64
console.log(buf.toString('hex')); // 转换为 16 进制
Buffer 常用于 Node.js 的流操作中:
const fs = require('fs');
const readStream = fs.createReadStream('file.txt');
readStream.on('data', (chunk) => {
// chunk 是一个 Buffer 对象
console.log('接收到数据块:', chunk.length, '字节');
console.log(chunk.toString());
});
Buffer 直接分配在 V8 堆外的内存,不受垃圾回收的影响。这意味着:
使用 Buffer.allocUnsafe() 时要注意:
防止 Buffer 溢出的建议:
// 错误示例
let buffers = [];
stream.on('data', (chunk) => {
buffers.push(chunk); // 可能导致内存泄漏
});
// 正确示例
let buffers = [];
stream.on('data', (chunk) => {
buffers.push(chunk);
if (buffers.length > 1000) {
// 处理数据并清空数组
Buffer.concat(buffers);
buffers = [];
}
});
// 处理特殊字符
const buf = Buffer.from('');
console.log(buf.length); // 4 字节
console.log(buf.toString().length); // 2 个字符
const fs = require('fs');
// 读取文件到 Buffer
const content = fs.readFileSync('file.txt');
// 写入 Buffer 到文件
fs.writeFileSync('output.txt', Buffer.from('Hello'));
const http = require('http');
http.createServer((req, res) => {
const chunks = [];
req.on('data', chunk => chunks.push(chunk));
req.on('end', () => {
const data = Buffer.concat(chunks);
// 处理完整的请求数据
});
}).listen(3000);