stream 模块
流是用于处理 Node.js 中的流数据(例如流媒体)的抽象接口。
与其他数据处理方法相比,流基本上提供了两个主要优势:
- 内存效率:在处理数据之前,无需在内存中加载大量数据
- 时间效率:获得数据后立即开始处理数据,而不必等到整个有效载荷传输完毕后再进行处理
Node.js 中有 4 种类型的流:
- Writable:可写流,可通过
fs.createWriteSteam()创建 - Readable:可读流,可通过
fs.createReadSteam()创建 - Duplex:双工流,即可读又可写,例如
net.Socket - Transform:转换流,也是一种双工流,可以对其他流进行数据转换
API
stream 模块提供用于实现流接口的 API。Node.js 提供了许多流对象,通常不需要使用 stream 模块来创建流。
可读流
创建可读流
stream模块有两种方法创建可读流- Readablejs
import { Readable } from 'stream' const readableStream = new Readable() - Readable.from( iterable, options )js
Readable.from('Good morning!', {encoding: 'utf8'})
- Readable
向可读流发送数据
jsreadableStream.push('ping!')从可读流读取数据
process.stdin是一个可读流,参考命令行输入输出,有两种不同的读取方式:- 流动模式:当数据块可用时,可读流会发出数据事件,然后执行回调js
let data = '' readableStream.on('data', chunk => data += chunk) - 暂停模式:调用
read()从内部缓冲区读取数据并返回,没有数据时返回null用以终止循环jslet data = '' readableStream.on('readable', , () => { let chunk while (null !== (chunk = readableStream.read())) { data += chunk } }
可读流都以暂停模式开始,可以通过以下方法切换为流动模式:
readableStream.on('data', callback)readableStream.resume()readableStream.pipe()
又可以通过以下方法切换回暂停模式:
readableStream.pause()readableStream.unpipe()删除管道以暂停因pipe()方法造成的流动。
- 流动模式:当数据块可用时,可读流会发出数据事件,然后执行回调
可写流
创建可写流
stream模块只有一种方法创建可读流- Readablejs
import { Writable } from 'stream' const writableStream = new Writable()
- Readable
向可写流写入数据
write()+end()jswritableStream.write('Hello ') writableStream.end('world!')pipe()将可读流的数据写入可写流js// 覆盖内置方法以观察写入数据 writableStream._write = (chunk, encoding, next) => { console.log(chunk.toString()) next() } readableStream.pipe( writableStream )
双工流
JavaScript 不支持多重继承,因此通过类 stream.Duplex 实现双工流。
stream.Duplex 原型继承自 stream.Readable,并寄生继承自 stream.Writable。因此具有可读流、可写流两者的API
转换流
转换流是双工流,但以一定方式将输入转换为输出。例如加密、解密、压缩、解压。
转换流原型继承自双工流,除了实现可读、可写外,还需实现 _transform() 方法,可选实现 _flush() 方法。