You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
const{ Readable }=require('stream');constinStream=newReadable({read(){}});inStream.on('data',(chunk)=>{console.log(chunk.toString())// 触发两次})inStream.push('ABCDEFGHIJKLM');inStream.push('NOPQRSTUVWXYZ');inStream.push(null);// No more datainStream.pipe(process.stdout);
stream 流
Node.js中,有四种基本类型流
fs.createWriteStream()
)fs.createReadStream()
)net.Socket
)zlib.createDeflate()
)Node.js创建的流都是运作在字符串和buffer(或Unit8Array)上。会以对象模式进行操作
缓冲
readable.readableBuffer
或writable.writableBuffer
来获取highWaterMark
选项,对于普通的流,指定了字节总数
,对于对象模式,指定了对象总数highWaterMark
的阈值,会暂停从底层资源读取数据(readable._read()
),知道当前缓冲数据被消费writable.write(chunk)
时,数据被缓冲在可写流中,当缓冲大小小于highWaterMark
的阈值,返回true,超过则返回falsestream.pipe()
),是为了限制数据的缓冲到可接受的程度,不会压垮内存主要的使用方法参照译文
有关Node.js Stream你所应该知道的
。源码阅读
这里只
Readable
和Writable
Writable
这里,构造函数只是单纯覆盖了几个option的传入方法,方面后续调用
可以看到,write方法最后就是调用了
_writev
/_write
方法,其中,_writev
会覆盖_write
。而这两个方法正是我们传入的两个方法,在构造函数上做了绑定Readable
可以看到,构造函数做了两件事情
read
方法以及destroy
方法read方法
要调用read方法,那么options中的read参数是必传的,否则无法在read方法中去调用
read方法做了这么几件事情
_read
方法读取数据push方法
push方法在推送null前,可以把数据保存在流中,以下是一个简单实例
源码部分
这里发现
push
方法是调用的readableAddChunk
方法,它的作用如下addChunk
方法在
addChunck
中,会把push进去的数据,放到state的buffer中缓存起来pipe方法
把内部定义的方法细节隐藏掉,可以看到pipe方法的整体框架
下面把细节方法展开
当有数据流动的时候,触发了data方法,这是pipe实现的关键方法
这个方法非常简单,只是把可读流读取的data,写入了可写流,在这里实现了pipe的功能
相当于只是帮助我们把这一层,后面有做无更多数据时的一些兜底处理,监听drain事件,暂停读取数据等等
首先是监听的结束事件,这里有两个点,一个是读取结束,一个是管道移除
其他的,不管是触发
close
还是error
还是可读流的unpipe
,都触发了unpipe
方法这个方法很简单,只是单纯地调用了可读流的
unpipe
在方法的最后,调用了resume方法。从文档可以得知,resume方法将被暂停的可读流恢复触发 'data' 事件,并将流切换到流动模式
这个方法是开始文件流读取的关键,在这里开始流式读取数据
最后在
stream.read(0)
开始读取数据,这个内部会触发push
方法,然后触发上面的maybeReadMore_
方法,连续不断地读取数据从fs的createReadStream和createWriteStream看stream类的调用
stream类,从根本上是一个EventEmiiter的一个对stream的定制的类。它并没有实际上的写入方法,只是封装了很多的事件和方法,让上层更易于去调用。
现在看看stream类的在fs上的
createReadStream
和createWriteStream
的调用,来从代码层面看看stream类的应用场景实例
这里,我们从一个文件读取数据,再通过
pipe
写入另一个文件,非常简单的几行代码fsStream
fs的
ReadStream
和WriteStream
通过lazyLoadStreams
方法引ReadStream
构造函数做了以下几件事情
下面主要来看下
open
方法WriteStream
WriteStream
比较简单,只是继承了Writable
,重写了write
方法。用fs
文件写入的方式,将流数据写入文件因为继承了
Writable
,内部的write方法直接调用了_write
方法进行写入举例在pipe上,有个可写流监听
data
事件,触发的write方法,也间接调用了_write
方法结语
至此,只是把stream的一部分内部代码进行了分析,还有很多诸如
duplex
以及transform
等等类未深入研究。The text was updated successfully, but these errors were encountered: