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()
方法。