Readable Stream
静止态paused和流动态flowing
可读的流是可以停止的,就是读着读着就突然不给你数据了(没办法继续读了)。
可读的流可以理解为是一个内容的生产者,当它不发内容了,他就处于一个静止的状态。当他又开始发内容了,他就处于一个流动态。
- 默认处于paused态
比如你去读一个文件,你不去pipe,不去监听(就是把下面红框的代码删掉),那么你读取了的文件的内容流向何处呢? 没有地方可以去,所以是静止态的。
- 添加data事件监听,他就变为flowing态
当你添加了pipe等事件之后,他就会开始流动了。
pipe是一个监听事件。pipe就是监听第一个流的data事件,然后把数据写到第二个流。
- 删掉data事件监听,他就变为paused态
也可以主动地改变流的状态
- pause() 可以将它变为paused
当处于paused的时候,用户就拿不到big_file.txt的数据了。
- resume() 可以将它变为flowing
Writable Stream
drain
drain 流干了事件,表示可以加点水了
背景
之前的文章:stream对象的原型、事件有详细说过https://www.yuque.com/u640022/lgv5t2/km8vrm
- 当我们调用stream.write(chunk)的时候,可能会得到false
- false的意思是 你写得太快了,数据积压了
- 这个时候我们不能在write了,要监听drain
- 等drain事件触发了,我们才能继续write
官方文档 有例子http://nodejs.cn/api/stream.html#stream_event_drain
改写这个例子
const fs = require('fs')
function writeOneMillionTimes(writer, data) {
let i = 1000000
write()
function write() {
let ok = true
do {
i--
if (i === 0) {
// Last time!
writer.write(data)
} else {
// See if we should continue, or wait.
// Don't pass the callback, because we're not done yet.
ok = writer.write(data)
if (ok === false) {
console.log('不能再写了')
}
}
} while (i > 0 && ok)
if (i > 0) {
// Had to stop early!
// Write some more once it drains.
writer.once('drain', () => {
console.log('干涸了')
write()
})
}
}
}
const writer = fs.createWriteStream('./big_file.txt')
writeOneMillionTimes(writer, 'hello world'
运行这个文件
就会不断的干涸,堵车。
finsh事件
触发finish事件需要两个条件
- 调用stream.end()之后,而且
- 缓冲区数据都已经传给底层系统之后 才触发finish
缓冲区的数据是什么:
当我们往文件写东西的时候,并不是直接写到文件里,或者说文件不是直接存到硬盘,而是有一个缓冲,到了一定程度之后才会写到硬盘(保存文件)