47 # 实现可读流

news/2025/1/15 15:36:03/

上一节讲了 fs.createReadStream 创建一个可读流,那么怎么查看它的源码是怎么实现的?

我们可以采用打断点的方式:我们可以看到先执行了 lazyLoadStreams 如果没有 ReadStream 就会 require 内部的 internal/fs/streams 模块

在这里插入图片描述
通过 internal/fs/streams.js 我们就能大概的知道 ReadStream 的大致实现
在这里插入图片描述
在这里插入图片描述

另外我们还可以直接下载 node 的源代码去看 ReadStream 的实现过程

打开官网:https://nodejs.org/zh-cn/download,或者通过 https://nodejs.org/dist/ 找自己想要看的版本

在这里插入图片描述
点击下载源代码,然后解压用 vscode 打开,找到 node-v18.16.1\lib\internal\fs\streams.js 即可

在这里插入图片描述
下面自己来实现可读流:

const EventEmitter = require("events");
const fs = require("fs");class KaimoReadStream extends EventEmitter {constructor(path, opts = {}) {super();this.path = path;this.flags = opts.flags || "r";this.mode = opts.mode || 0o666;this.autoClose = opts.autoClose || true;this.start = opts.start || 0;this.end = opts.end || 0o666;// 读取的数量默认是 64kthis.highWaterMark = opts.highWaterMark || 64 * 1024;// 记录读取的偏移量this.pos = this.start;// 默认创建一个可读流,是非流动模式,不会触发 data 事件,如果用户监听了 data 事件后,需要变为流动模式// 是否是流动模式this.flowing = false;this.on("newListener", (type) => {// 如果用户监听了 dataif (type === "data") {this.flowing = true;this.read();}});// 打开文件this.open();}open() {fs.open(this.path, this.flags, this.mode, (err, fd) => {if (err) {return this.emit("error", err);}// 将 fd 保存到实例上,用于稍后的读取操作this.fd = fd;this.emit("open", fd);});}// 利用发布订阅来实现延迟执行read() {// 读取必须要等待文件打开完毕,如果打开了会触发 open 事件if (typeof this.fd !== "number") {// 如果没有 fd 就返回一个 open 的一次性事件,再去回调 read 方法return this.once("open", () => this.read());}console.log("KaimoReadStream---->", this.fd);// 真正开始读取const buffer = Buffer.alloc(this.highWaterMark);// 每次理论上应该读取 highWaterMark 个,但是用户能指定读取的位置// 应该读几个(不要读超了)let howMuchToRead = this.end ? Math.min(this.end - this.pos + 1, this.highWaterMark) : this.highWaterMark;fs.read(this.fd, buffer, 0, howMuchToRead, this.pos, (err, bytesRead) => {if (bytesRead) {this.pos += bytesRead;this.emit("data", buffer.slice(0, bytesRead));if (this.flowing) {this.read();}} else {this.emit("end");if (this.autoClose) {fs.close(this.fd, () => {this.emit("close");});}}});}pause() {this.flowing = false;}resume() {this.flowing = true;this.read();}
}module.exports = KaimoReadStream;

测试:

const KaimoReadStream = require("./47/KaimoReadStream");
const path = require("path");let rs = new KaimoReadStream(path.resolve(__dirname, "./47/name.txt"), {flags: "r", // r 代表读取encoding: null, // 默认 null,就是 buffer 类型的mode: 0o666, // 模式:可读可写autoClose: true, // fs.closestart: 0, // 0 - 8 包前又包后end: 8,highWaterMark: 3 // 每次读取的个数
});
// console.log(rs);let bufferArr = [];
// 监听 open(文件流特殊的事件,普通流没有)
rs.on("open", (fd) => {console.log("open---->", fd);
});
// 监听 data
rs.on("data", (data) => {console.log("data---->", data, data.toString());bufferArr.push(data);// rs.pause 可以让可读流暂停触发 data 事件rs.pause();console.log("pause---->暂停");// 再次触发 data 事件,可以使用 rs.resumesetTimeout(() => {console.log("过 2s 再次触发 data 事件");rs.resume();}, 2000);
});
// 监听 end
rs.on("end", () => {console.log("end---->", Buffer.concat(bufferArr).toString());
});
// 监听 error
rs.on("error", (err) => {console.log("err---->", err);
});
// 监听 close (文件流特殊的事件,普通流没有)
rs.on("close", () => {console.log("close---->");
});

在这里插入图片描述


http://www.ppmy.cn/news/709811.html

相关文章

医药电商平台解决方案

医药行业电商平台搭建方案 医药行业的发展走向: 2018年全国七大类医药商品销售总额为21800亿元,较上年同比增长9%。随着医药卫生体制改革的不断深入,药品行业积极顺应政策导向,呈现增长平稳、结构优化、质量升级的发展态势。资本…

电商平台-供应链模块的设计与架构

说明:Java开源生鲜电商平台中供应链模块属于卖家的行为,也就是卖家如何管理他们自己的供应商,包括结算方式,压款方式,结算周期等等,超出了我这个B2B平台所提供的服务范畴,但是这块也是非常重要的…

简单介绍在线OTA几款平台

看好在线旅游平台——飞猪,携程,途牛,美团,马蜂窝,去哪儿旅行,同程(艺龙),马蜂窝,去哪儿旅行,京东旅行和驴妈妈。 在线旅游(OTA&…

小型电商平台系统需求分析文档

小型电商平台系统需求分析文档 摘要第1章 引言1.1 项目背景1.2 基于B/S架构的电子商务网站的研究现状1.2.1 电子商务网站的基本框架1.2.2 国内电子商务的发展1.2.3 国外电子商务的发展 1.3 课题背景及开展研究的意义1.3.1 电子商务网站研究背景1.3.2 电子商务网站开展研究的意义…

变革家五步投资法学习体会

变革家(Reformer),专注创业项目分析,帮股权投资者把好第一关! 拆解学院,是变革家的一个王牌课程,通过每周微信语音和网站内容形式,大力提升股权投资者的投资水平。 作为一名变革家的顶级Fans&am…

腾讯阿里投资领域

分类腾讯阿里人工智能UBTECH、工匠社、乐聚智能、云迹科技、Wonder Workshop、Element AI、特斯拉、Petuum、猿题库、恒安嘉新、碳云智能、阿凡题、CloudMedx、Scaled Inference商汤科技、旷视科技、深鉴科技、寒武纪科技、新华智云、Kneron、Video、思必驰、Softbankrobotics、…

大数据平台建设实施方案

实施方案 实施思路 基于平台目标、政策、规划以及现状的了解,建议采用“长期规划,分步实施”的建设思路: 长期规划:对数据中心及决策支持系统进行长、中、短期的规划,对于投入小、见效快的内容纳入短期规划&#xff…

大数据平台建设关键技术

平台关键技术设计 架构风格 云计算 Google在2006年率先提出“云计算”的概念。所谓“云计算”,是一种大规模的分布式模型,通过网络将抽象的、可伸缩的、便于管理的数据能源、服务、存储方式等传递给终端用户。狭…