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() // 转 JSONBuffer.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) => {}) // 子进程通信
Cao Note