失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 解读 Node 核心模块 Stream 系列一( Readable )

解读 Node 核心模块 Stream 系列一( Readable )

时间:2024-05-03 11:25:00

相关推荐

解读 Node 核心模块 Stream 系列一( Readable )

node中的流

node中stream模块是非常,非常,非常重要的一个模块,因为很多模块都是这个模块封装的:

Readable:可读流,用来读取数据,比如 fs.createReadStream()。Writable:可写流,用来写数据,比如 fs.createWriteStream()。Duplex:双工流,可读+可写,比如 net.Socket()。Transform:转换流,在读写的过程中,可以对数据进行修改,比如 zlib.createDeflate()(数据压缩/解压)。

系列链接

解读 Node 核心模块 Stream 系列一( Readable )解读Node核心模块Stream系列一(Writable和pipe)

node中流的实现:

node中stream是一个类,它继承自Event模块,所以可以通过事件订阅的方式来修改内部的状态或者调用外部的回调,我们可以从源码node/lib/internal/streams/legacy.js看到:

node中stream(node/lib/stream.js)包括了主要包括了四个部分:

lib/_stream_readable.jslib/_stream_writable.jslib/_stream_tranform.jslib/_stream_duplex.js

Readble

Readble的例子

客户端上的 HTTP 响应服务器上的 HTTP 请求fs 读取的流zlib 流crypto 流TCP socket子进程 stdout 与 stderrprocess.stdin

Readable的特点和简化实现:

特点
Readable拥有一个通过BufferList生成的缓存链表buffer,用来缓存读取到的chunk(对于非对象模式的流,数据块可以是字符串或 Buffer。对于对象模式的流,数据块可是除 null 以外的任意 JavaScript 值),同时有一个length来记录buffer的长度Readable拥有一个highWaterMark来标明buffer的最大容量,通过和length比较决定是否需要补充缓存Readable订阅 eadble事件来触发read()消费者从缓存中消耗数据Readable拥有read()从缓存区读取数据的同时也会根据标志判断是否调用生产者补充缓存区Readable拥有reading来标明消费者正在消耗Readable拥有howMatchToRead()来随时调整读取的大小,防止对buffer过多的读取,导致会读取乱码的部分Readable拥有fromList()来根据读取大小的不同,随时调整buffer中的链表结构

由于node原码的可读流有将近一千行的代码,其中有大量的异常处理,debug调试,各种可读流的兼容处理,加码解码处理等,所以这里采取一个简化版的实现,源码中使用链表作为buffer,这里采用数组进行简化,主要是阐述可读流的处理过程。

构造函数
Readable拥有一个通过BufferList生成的缓存链表buffer,用来缓存读取到的chunk(对于非对象模式的流,数据块可以是字符串或 Buffer。对于对象模式的流,数据块可是除 null 以外的任意 JavaScript 值),同时有一个length来记录buffer的长度Readable拥有一个highWaterMark来标明buffer的最大容量,通过和length比较决定是否需要补充缓存Readable订阅 eadble事件来触发read()消费者从缓存中消耗数据

const EE = require(events);const util = require(util);const fs = require(fs);function Readable(path,options) {//这个参数是源码没有的,这里主要是为了读取fs为案例加的EE.call(this);//构造函数继承EventEmiterthis.path = path;this.autoClose = options.autoClose || true;this.highWaterMark = options.highWaterMark || 64 * 1024;//64kthis.encoding = options.encoding || null;this.flags = options.flags || ; 这个源码没有的,这里主要是为了fs读取案例加的this.needEmitReadable = false;// 需要触发readable事件,默认不需要this.position = 0;// 偏移量this.cache = []; // 缓存区this.reading = false;// 是否正在从缓存中读取,消费者消耗中this.length = 0; // 缓存区大小,控制长度this

如果觉得《解读 Node 核心模块 Stream 系列一( Readable )》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。