本文目录导读:

我来为你介绍几个缓冲区(Buffer)的典型案例,涵盖不同应用场景:
基本读写案例
// 创建和操作缓冲区
const buf = Buffer.from('Hello World', 'utf8');
// 读取缓冲区
console.log(buf.toString()); // Hello World
console.log(buf.length); // 11 字节
// 部分读取
console.log(buf.toString('utf8', 0, 5)); // Hello
// 修改缓冲区
buf[0] = 104; // 'h' 的ASCII码
console.log(buf.toString()); // hello World
网络数据传输案例
const net = require('net');
// TCP服务器处理二进制数据
const server = net.createServer((socket) => {
// 收集数据块
const chunks = [];
let totalLength = 0;
socket.on('data', (chunk) => {
// 将接收到的Buffer片段存储
chunks.push(chunk);
totalLength += chunk.length;
// 假设我们期望接收固定大小的数据包
if (totalLength >= 4) {
// 合并所有Buffer片段
const completeBuffer = Buffer.concat(chunks);
// 解析数据包
const messageLength = completeBuffer.readUInt32BE(0);
const message = completeBuffer.slice(4, 4 + messageLength);
console.log('收到消息:', message.toString());
// 发送响应
const response = Buffer.from('ACK\n', 'utf8');
socket.write(response);
chunks.length = 0;
totalLength = 0;
}
});
socket.on('error', (err) => console.error('Socket错误:', err));
});
server.listen(3000, () => {
console.log('服务器监听端口3000');
// 创建客户端测试
setTimeout(() => {
const client = net.connect(3000);
const message = 'Hello Server';
const dataBuffer = Buffer.alloc(4 + message.length);
dataBuffer.writeUInt32BE(message.length, 0);
dataBuffer.write(message, 4, 'utf8');
client.write(dataBuffer);
client.on('data', (data) => console.log('服务器响应:', data.toString()));
client.end();
}, 100);
});
文件处理的缓冲区案例
const fs = require('fs');
// 高效的文件流处理
function readLargeFile(filePath) {
const chunks = [];
let fileSize = 0;
const stream = fs.createReadStream(filePath, { highWaterMark: 64 * 1024 }); // 64KB块
stream.on('data', (chunk) => {
chunks.push(chunk);
fileSize += chunk.length;
// 实时处理每个缓冲区块
console.log(`读取块: ${chunk.length} 字节`);
// 查找特定字节模式
const search = Buffer.from('IMPORTANT');
const index = chunk.indexOf(search);
if (index !== -1) {
console.log(`在偏移 ${fileSize - chunk.length + index} 处找到关键字`);
}
});
stream.on('end', () => {
console.log(`文件读取完成,总大小: ${fileSize} 字节`);
const allData = Buffer.concat(chunks);
return allData;
});
stream.on('error', (err) => console.error('读取错误:', err));
}
// 创建测试文件
fs.writeFileSync('test.txt', '这是一个测试文件\n包含IMPORTANT关键信息'.repeat(100));
readLargeFile('test.txt');
图像处理的缓冲区案例
// 简单的BMP图像处理示例
function processImageBuffer(buffer) {
// BMP文件头:前14字节包含文件信息
if (buffer.length < 54) {
throw new Error('非有效的BMP文件');
}
// 解析BMP头信息
const fileSize = buffer.readUInt32LE(2);
const dataOffset = buffer.readUInt32LE(10);
const width = buffer.readInt32LE(18);
const height = buffer.readInt32LE(22);
const bitsPerPixel = buffer.readUInt16LE(28);
console.log(`BMP图像信息: ${width}x${height}, ${bitsPerPixel}位色`);
// 图像数据处理示例:反转颜色
const pixelDataStart = dataOffset;
const pixelData = buffer.slice(pixelDataStart);
if (bitsPerPixel === 24) { // 24位色(RGB)
for (let i = 0; i < pixelData.length; i += 3) {
// 反转RGB值
const temp = pixelData[i];
pixelData[i] = pixelData[i + 2];
pixelData[i + 2] = temp;
}
}
return buffer; // 返回处理后的图像
}
// 创建测试用的最小BMP
function createTestBMP(width, height) {
const dataSize = width * height * 3;
const offset = 54;
const buffer = Buffer.alloc(offset + dataSize);
// 文件头
buffer.write('BM', 0); // 签名
buffer.writeUInt32LE(offset + dataSize, 2); // 文件大小
buffer.writeUInt32LE(0, 6); // 预留
buffer.writeUInt32LE(offset, 10); // 数据偏移
// DIB头
buffer.writeUInt32LE(40, 14); // DIB头大小
buffer.writeInt32LE(width, 18);
buffer.writeInt32LE(height, 22);
buffer.writeUInt16LE(1, 26); // 平面数
buffer.writeUInt16LE(24, 28); // 位深度
buffer.writeUInt32LE(0, 30); // 压缩
buffer.writeUInt32LE(dataSize, 34); // 图像大小
// 填充像素数据(示例:红色)
for (let i = offset; i < buffer.length; i += 3) {
buffer[i] = 0; // B
buffer[i+1] = 0; // G
buffer[i+2] = 255; // R
}
return buffer;
}
// 测试
const testBMP = createTestBMP(100, 100);
console.log('原始BMP大小:', testBMP.length);
const processedBMP = processImageBuffer(testBMP);
console.log('图像处理完成');
数据包解析案例
// 解析自定义协议的数据包
class DataPacketParser {
constructor() {
this.buffer = Buffer.alloc(0);
this.callbacks = [];
}
// 添加解析回调
onPacket(callback) {
this.callbacks.push(callback);
}
// 处理接收的数据
handleData(data) {
// 合并到缓冲区
this.buffer = Buffer.concat([this.buffer, data]);
while (this.buffer.length >= 8) { // 最小包头8字节
// 检查包头
const magic = this.buffer.readUInt16LE(0);
if (magic !== 0xABCD) {
console.error('无效的包头');
// 跳过无效字节
this.buffer = this.buffer.slice(1);
continue;
}
// 解析包头
const packetLength = this.buffer.readUInt16LE(2);
const type = this.buffer.readUInt8(4);
const flags = this.buffer.readUInt8(5);
const checksum = this.buffer.readUInt16LE(6);
// 检查数据包完整性
if (this.buffer.length >= packetLength + 8) {
// 提取数据
const payload = this.buffer.slice(8, 8 + packetLength);
// 解析数据包
const packet = {
type,
flags,
checksum,
payload: payload.toString('utf8')
};
// 调用回调
this.callbacks.forEach(cb => cb(packet));
// 移除已处理的数据
this.buffer = this.buffer.slice(8 + packetLength);
} else {
// 等待更多数据
break;
}
}
}
}
// 创建协议包
function createDataPacket(type, data) {
const payload = Buffer.from(data, 'utf8');
const buffer = Buffer.alloc(8 + payload.length);
buffer.writeUInt16LE(0xABCD, 0); // 魔术字节
buffer.writeUInt16LE(payload.length, 2); // 数据长度
buffer.writeUInt8(type, 4); // 类型
buffer.writeUInt8(0, 5); // 标志位
// 简单校验和
let sum = 0;
for (let i = 0; i < payload.length; i++) {
sum = (sum + payload[i]) & 0xFFFF;
}
buffer.writeUInt16LE(sum, 6);
payload.copy(buffer, 8);
return buffer;
}
// 测试
const parser = new DataPacketParser();
parser.onPacket((packet) => {
console.log(`收到数据包 - 类型: ${packet.type}, 数据: "${packet.payload}"`);
});
// 模拟接收数据块(可能被分片)
const packet1 = createDataPacket(1, 'Hello');
const packet2 = createDataPacket(2, 'World');
// 发送前半部分
parser.handleData(packet1.slice(0, 5));
// 发送后半部分和第二个包
parser.handleData(Buffer.concat([packet1.slice(5), packet2]));
性能优化案例
// Buffer池化技术
class BufferPool {
constructor(poolSize = 1024, bufferSize = 8192) {
this.poolSize = poolSize;
this.bufferSize = bufferSize;
this.freeBuffers = [];
this.inUse = new Set();
this.initialize();
}
initialize() {
for (let i = 0; i < this.poolSize; i++) {
this.freeBuffers.push(Buffer.alloc(this.bufferSize));
}
}
acquire() {
let buffer = this.freeBuffers.pop();
if (!buffer) {
// 池已耗尽,创建新的
buffer = Buffer.alloc(this.bufferSize);
console.warn('Buffer池已耗尽,创建新缓冲区');
} else {
buffer.fill(0); // 清空旧数据
}
this.inUse.add(buffer);
return buffer;
}
release(buffer) {
if (this.inUse.has(buffer)) {
this.inUse.delete(buffer);
this.freeBuffers.push(buffer);
} else {
console.error('尝试释放不存在的缓冲区');
}
}
getPoolStats() {
return {
total: this.poolSize,
inUse: this.inUse.size,
free: this.freeBuffers.length
};
}
}
// 使用示例
const pool = new BufferPool(5, 100);
// 模拟并发任务
function processData(data) {
const buffer = pool.acquire();
console.log(`获取缓冲区,状态:`, pool.getPoolStats());
// 模拟数据处理
setTimeout(() => {
buffer.write(data);
console.log(`处理: "${buffer.toString('utf8', 0, data.length)}"`);
// 释放缓冲区
pool.release(buffer);
console.log(`释放缓冲区,状态:`, pool.getPoolStats());
}, 100);
}
// 并发处理
processData('任务1');
processData('任务2');
processData('任务3');
processData('任务4');
processData('任务5');
processData('任务6'); // 这将导致池耗尽警告
二进制协议编解码案例
// 定长和变长字段的处理
class BinaryProtocol {
// 编码
static encode({ id, name, scores, tags }) {
// 计算所需缓冲区大小
const nameBuffer = Buffer.from(name, 'utf8');
const tagsBuffer = Buffer.concat(tags.map(t => {
const tagBuf = Buffer.from(t, 'utf8');
const lenBuf = Buffer.alloc(1);
lenBuf.writeUInt8(tagBuf.length);
return Buffer.concat([lenBuf, tagBuf]);
}));
const count = scores.length;
const totalSize = 2 + 1 + nameBuffer.length + 1 + count * 4 + 1 + tagsBuffer.length;
const buffer = Buffer.alloc(totalSize);
let offset = 0;
// ID (2字节)
buffer.writeUInt16LE(id, offset);
offset += 2;
// 名字长度 (1字节)
buffer.writeUInt8(nameBuffer.length, offset);
offset += 1;
// 名字数据
nameBuffer.copy(buffer, offset);
offset += nameBuffer.length;
// 分数数量 (1字节)
buffer.writeUInt8(count, offset);
offset += 1;
// 分数数组 (每个4字节)
scores.forEach(score => {
buffer.writeFloatLE(score, offset);
offset += 4;
});
// 标签数量 (1字节)
buffer.writeUInt8(tags.length, offset);
offset += 1;
// 标签数据
tagsBuffer.copy(buffer, offset);
return buffer;
}
// 解码
static decode(buffer) {
let offset = 0;
// 解析ID
const id = buffer.readUInt16LE(offset);
offset += 2;
// 名字
const nameLen = buffer.readUInt8(offset);
offset += 1;
const name = buffer.toString('utf8', offset, offset + nameLen);
offset += nameLen;
// 分数
const scoreCount = buffer.readUInt8(offset);
offset += 1;
const scores = [];
for (let i = 0; i < scoreCount; i++) {
scores.push(buffer.readFloatLE(offset));
offset += 4;
}
// 标签
const tagCount = buffer.readUInt8(offset);
offset += 1;
const tags = [];
for (let i = 0; i < tagCount; i++) {
const tagLen = buffer.readUInt8(offset);
offset += 1;
tags.push(buffer.toString('utf8', offset, offset + tagLen));
offset += tagLen;
}
return { id, name, scores, tags };
}
}
// 测试
const data = {
id: 42,
name: '张三',
scores: [89.5, 92.3, 78.8],
tags: ['优秀', '进步', '努力']
};
const encoded = BinaryProtocol.encode(data);
console.log('编码后大小:', encoded.length, '字节');
const decoded = BinaryProtocol.decode(encoded);
console.log('解码数据:', decoded);
- 缓冲区分片处理:处理大数据时要分片,避免内存溢出
- Buffer复用:使用池化技术,避免频繁创建/销毁
- 内存安全:及时释放不再使用的Buffer,防止内存泄漏
- 边界检查:始终验证读取/写入的字节范围
- 性能优化:预分配缓冲区,减少动态扩容
- 错误处理:对空缓冲区、无效数据等做好异常处理
这些案例展示了Buffer在不同场景中的应用,从基本的读写操作到复杂的协议处理,都是Node.js开发中常见的情况。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播