stream 模块(一)
Stream
流是一组有序的,有起点和终点的字节数据传输手段,它不关心文件的整体内容,只关注是否从文件中读到了数据,以及读到数据之后的处理。流(stream)是 Node.js 中处理流式数据的抽象接口。 stream 模块用于构建实现了流接口的对象。
流可以是可读的、可写的、或者可读可写的。 所有的流都是 EventEmitter 的实例。
流是基于事件的
Node.js 中 流有四种基本类型:
1 Readable,可读流 。例如 fs.createReadStream
2 Writeable,可写流。例如 fs.createWriteStream
3 Duplex,双向流(可读可写流)。例如 net.Socket
4 Transform ,转换流(在读写过程中可以修改和变换数据的 Duplex), 例如 zlib.createDeflate
为什么需要流
对于 读取体积比较小的文件,流的优势可能没有那么明显,但是 读取一个有 几百 M 甚至 几个 G 的文件时候,直接读取会消耗大量的内存,导致 因内存占用过多 使系统卡顿或者崩溃;其次,我们的网速 内存 和 cpu 运算速度都是有限的,一次性加载 这么大的文件 会非常 缓慢。
采用流的方式, 当读取一个较大的文件时,我们不必将整个文件加载到内存中,每次只需读取一部分,然后将这部分传输,在读取一部分... 就像水流一样。就像 在线看电影,每次一点点将视频 流动到 本地的播放器,一边流动一边播放,最后 视频流动完也就播放结束了。
可读流
可读流可以想象成水龙头,是数据的源头。
可读流运作于两种模式之一:流动模式(flowing)或 暂停模式(paused)
readable
readable 事件能让我们自己控制每次读取的大小 和 次数。
可读流
可读流的常用方法
pipe(), read()
简单实现可读流
1
2
3
4
流中的数据有两种模式,二进制模式 (二进制模式,每个分块都是 buffer 或者 string 对象 )和 对象模式 (流内部处理的是一系列普通对象)
可读流的两种模式
可读流运作于两种模式之一:流动模式(flowing)或暂停模式(paused)
所有可读流都开始于暂停模式,可以通过以下方式切换到流动模式:
1 添加'data'事件句柄。
2 调用stream.resume()方法。
3 调用stream.pipe()方法将数据发送到可写流。
可读流可以通过以下方式切换回暂停模式:
1 如果没有管道目标,则调用stream.pause()。
2 如果有管道目标,则移除所有管道目标。调用stream.unpipe()可以移除多个管道目标。
3 只有提供了消费或忽略数据的机制后,可读流才会产生数据。 如果消费的机制被禁用或移除,则可读流会停止产生数据。
如果可读流切换到流动模式,且没有可用的消费者来处理数据,则数据将会丢失(简单来说:流动模式不缓存,直接发射 data, 然后读取下次的数据,如果处于流动模式,且没有消费,那么数据就会丢失)。例如,当调用 readable.resume() 时,没有监听 'data' 事件或 'data' 事件句柄已移除。
添加'readable'事件句柄会使流自动停止流动,并通过readable.read()消费数据。 如果'readable'事件句柄被移除,且存在'data'事件句柄,则流会再次开始流动。
可写流
可写流可以想象成 水杯
想象成水桶
可写流写数据必须是字符串类型或者 buffer 类型
三个常用方法 write() ,end() , on()
ws.on('drain') 当读入的文件全部写入后 就恢复读取
简单实现可写流
2
3
4