Skip to content

Node.js 流与 Buffer ​

Buffer 缓冲区 ​

Buffer 用于处理二进制数据,是 Node.js 全局对象,无需引入。

创建 Buffer ​

js
// 创建指定大小的 Buffer(推荐)
const buf1 = Buffer.alloc(10)                    // 初始化为 0
const buf2 = Buffer.alloc(10, 'fill')            // 用 'fill' 填充

// 从数据创建
const buf3 = Buffer.from('Hello')                // 字符串 → Buffer
const buf4 = Buffer.from([0x68, 0x65, 0x6c])     // 字节数组 → Buffer
const buf5 = Buffer.from('你好', 'utf-8')         // 指定编码
// 创建指定大小的 Buffer(推荐)
const buf1 = Buffer.alloc(10)                    // 初始化为 0
const buf2 = Buffer.alloc(10, 'fill')            // 用 'fill' 填充

// 从数据创建
const buf3 = Buffer.from('Hello')                // 字符串 → Buffer
const buf4 = Buffer.from([0x68, 0x65, 0x6c])     // 字节数组 → Buffer
const buf5 = Buffer.from('你好', 'utf-8')         // 指定编码

读写 Buffer ​

js
const buf = Buffer.alloc(6)

buf[0] = 0x68          // 通过索引读写字节
console.log(buf[0])    // 104 (0x68)

buf.write('Hello')     // 写入字符串
console.log(buf.toString())  // 'Hello'
console.log(buf.toString('hex'))  // 十六进制字符串
const buf = Buffer.alloc(6)

buf[0] = 0x68          // 通过索引读写字节
console.log(buf[0])    // 104 (0x68)

buf.write('Hello')     // 写入字符串
console.log(buf.toString())  // 'Hello'
console.log(buf.toString('hex'))  // 十六进制字符串

常用方法 ​

js
Buffer.isBuffer(obj)              // 是否为 Buffer
Buffer.concat([buf1, buf2])       // 合并多个 Buffer
buf.length                        // Buffer 字节长度
buf.slice([start, end])           // 截取部分 Buffer
buf.toJSON()                      // 转 JSON
Buffer.isBuffer(obj)              // 是否为 Buffer
Buffer.concat([buf1, buf2])       // 合并多个 Buffer
buf.length                        // Buffer 字节长度
buf.slice([start, end])           // 截取部分 Buffer
buf.toJSON()                      // 转 JSON

应用场景 ​

  • 文件读写:fs.readFile() 默认返回 Buffer
  • 网络通信:TCP/UDP 数据传输以 Buffer 形式
  • 加密解密:crypto 模块操作二进制数据

Stream 流 ​

流(Stream)是 Node.js 处理数据的抽象接口,适用于大文件或持续数据。

流的类型 ​

类型说明示例
Readable可读流fs.createReadStream()
Writable可写流fs.createWriteStream()
Duplex可读可写net.Socket
Transform转换流(读写时可修改数据)zlib.createGzip()

可写流 — createWriteStream ​

js
const fs = require('fs')

const ws = fs.createWriteStream('output.txt', { flags: 'w', encoding: 'utf-8' })

ws.on('open', () => console.log('文件打开'))
ws.on('close', () => console.log('文件写入完成'))

ws.write('Hello World!\n')
ws.write('第二行内容\n')
ws.end(() => console.log('写入结束'))
const fs = require('fs')

const ws = fs.createWriteStream('output.txt', { flags: 'w', encoding: 'utf-8' })

ws.on('open', () => console.log('文件打开'))
ws.on('close', () => console.log('文件写入完成'))

ws.write('Hello World!\n')
ws.write('第二行内容\n')
ws.end(() => console.log('写入结束'))

可读流 — createReadStream ​

js
const fs = require('fs')

const rs = fs.createReadStream('input.txt', { encoding: 'utf-8' })

rs.on('open', () => console.log('打开成功'))
rs.on('data', (chunk) => {
  console.log('接收到数据块:', chunk.length)
})
rs.on('end', () => console.log('读取结束'))
rs.on('error', (err) => console.error(err))
const fs = require('fs')

const rs = fs.createReadStream('input.txt', { encoding: 'utf-8' })

rs.on('open', () => console.log('打开成功'))
rs.on('data', (chunk) => {
  console.log('接收到数据块:', chunk.length)
})
rs.on('end', () => console.log('读取结束'))
rs.on('error', (err) => console.error(err))

管道流 — pipe ​

pipe 自动处理数据从可读流到可写流的传输:

js
const rs = fs.createReadStream('source.txt')
const ws = fs.createWriteStream('target.txt')

rs.pipe(ws)

ws.on('finish', () => {
  console.log('写入完成')
  ws.end()
})
const rs = fs.createReadStream('source.txt')
const ws = fs.createWriteStream('target.txt')

rs.pipe(ws)

ws.on('finish', () => {
  console.log('写入完成')
  ws.end()
})

链式管道 ​

js
const zlib = require('zlib')
const fs = require('fs')

fs.createReadStream('source.txt')
  .pipe(zlib.createGzip())       // 压缩
  .pipe(fs.createWriteStream('source.txt.gz'))
const zlib = require('zlib')
const fs = require('fs')

fs.createReadStream('source.txt')
  .pipe(zlib.createGzip())       // 压缩
  .pipe(fs.createWriteStream('source.txt.gz'))

EventEmitter 事件触发器 ​

Node.js 核心 API 基于异步事件驱动架构,EventEmitter 是事件机制的核心。

基本用法 ​

js
const EventEmitter = require('events')
const event = new EventEmitter()

// 监听事件
event.on('test', (data) => {
  console.log(data)
})

// 派发事件
event.emit('test', 'Hello EventEmitter')
const EventEmitter = require('events')
const event = new EventEmitter()

// 监听事件
event.on('test', (data) => {
  console.log(data)
})

// 派发事件
event.emit('test', 'Hello EventEmitter')

常用方法 ​

js
// 只监听一次
event.once('test', (data) => {
  console.log(data)  // 只会触发一次
})

// 取消监听
const fn = (msg) => console.log(msg)
event.on('test', fn)
event.off('test', fn)  // 移除特定监听器

// 移除所有监听器
event.removeAllListeners('test')

// 设置最大监听数量(默认 10)
event.setMaxListeners(20)
console.log(event.getMaxListeners())
// 只监听一次
event.once('test', (data) => {
  console.log(data)  // 只会触发一次
})

// 取消监听
const fn = (msg) => console.log(msg)
event.on('test', fn)
event.off('test', fn)  // 移除特定监听器

// 移除所有监听器
event.removeAllListeners('test')

// 设置最大监听数量(默认 10)
event.setMaxListeners(20)
console.log(event.getMaxListeners())

发布订阅模式 ​

发布者 → 调度中心(EventEmitter)→ 订阅者
发布者 → 调度中心(EventEmitter)→ 订阅者

当一个发布者有新消息时,发布到调度中心,调度中心通知所有订阅者。实现了解耦。

应用场景 ​

process 对象继承自 EventEmitter:

js
process.on('exit', (code) => {})
process.on('uncaughtException', (err) => {})
process.on('message', (data) => {})   // 子进程通信
process.on('exit', (code) => {})
process.on('uncaughtException', (err) => {})
process.on('message', (data) => {})   // 子进程通信