56 # 实现 pipe 方法进行拷贝

pipe 是异步的,可以实现读一点写一点,管道的优势:不会淹没可用内存,但是在导入的过程中无法获取到内容

const fs = require("fs");
const path = require("path");fs.createReadStream(path.resolve(__dirname, "./56/name.txt")).pipe(fs.createWriteStream(path.resolve(__dirname, "./56/copy_name.txt")));

我们新建文件 name.txt 里面添加文本

kaimo123456789

在这里插入图片描述

下面在我们的可读流里添加 pipe 方法:上一节实现的可写流直接拿过来用即可

在这里插入图片描述

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;// 读取的数量默认是 64k 如果文件大于 64k 就可以采用流的方式this.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();}// 管道pipe(dest) {this.on("data", (data) => {let flag = dest.write(data);console.log("pipe--flag-->", flag, data.toString());if (!flag) {this.pause();}});dest.on("drain", () => {this.resume();});}
}module.exports = KaimoReadStream;

测试一下

const path = require("path");// 默认读 4 写 1
const KaimoReadStream = require("./56/KaimoReadStream"); // 64k
const KaimoWriteStream = require("./56/KaimoWriteStream"); // 16klet rs = new KaimoReadStream(path.resolve(__dirname, "./56/name.txt"), {highWaterMark: 4
});
// 先写1个,3个放缓存
let ws = new KaimoWriteStream(path.resolve(__dirname, "./56/copy_name2.txt"), {highWaterMark: 1
});
rs.pipe(ws);

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/3339.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端 | (七)浮动 | 尚硅谷前端html+css零基础教程2023最新

学习来源:尚硅谷前端htmlcss零基础教程,2023最新前端开发html5css3视频 文章目录 📚浮动介绍🐇元素浮动后的特点🐇浮动小练习🔥盒子1右浮动🔥盒子1左浮动🔥所有盒子都浮动&#x1f5…

数学建模 插值算法

有问题 牛顿差值也有问题它们都有龙格现象,一般用分段插值。 插值预测要比灰色关联预测更加准确,灰色预测只有2次 拟合样本点要非常多,样本点少差值合适

Spring底层

配置文件 配置优先级 之前讲解过,可以用这三种方式进行配置 那如果这三种都进行了配置,那到底哪一份生效呢? 结论 优先级从大到小 properties>yml>yaml然后就是现在一般都用yml文件进行配置 其他配置方式 除了配置文件外 还有不同…

电压放大器在超声波焊接中的作用以及应用

电压放大器是一种运用于电子设备中的信号放大器,主要作用是将小信号放大为更高幅度的信号。在超声波焊接中,电压放大器起到了重要的作用,它可以将从传感器采集到的微小信号放大为能够被检测和处理的合适大小的信号。 超声波焊接是现代工业生产…

微信怎么自动加好友,通过好友后自动打招呼

很多客户朋友每天花大量的时间用手机搜索添加好友,这样的添加很集中也容易频繁,而且效率还低。对方通过后,有时也不能及时和客户搭建链接,导致客户也流失了。 现在可以实现自动添加和自动打招呼哦,只需要导入数据、设置…

【从零开始学CSS | 第二篇】伪类选择器

目录 前言: 伪类选择器: 常见的伪类选择器: 举例: 小窍门: 总结: 前言: 上一篇文章我们详细的为大家介绍了一些常见的选择器,这几篇我们将再次介绍CSS中的一个常见选择器——伪类选择器&am…

设计模式之适配器模式

写在前面 适配器设计模式属于结构型设计模式的一种,本文一起来看下。 1:介绍 1.1:什么时候适配器设计模式 当现有接口客户端无法直接调用时,我们可以考虑适配器设计模式,来定义一个能够供客户端直接调用的接口&…

软件测试的分类

代码分类: 1、黑盒测试 2、白盒测试 3、灰黑测试 黑盒测试: 把测试的对象看成是一个黑色的盒子的,看不到里面内部的结构,是对软件的一种功能性的测试。 白盒测试: 就是把测试的对象看成是一个透明的盒子&#x…

测试老鸟总结,性能测试-最佳并发和最大并发,性能测试实施...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 性能测试&#xf…

curl操作

下载路径:https://curl.se/windows/ 参考:https://blog.csdn.net/weixin_45191386/article/details/130652821 操作: curl http://localhost:8085/api/v1/aaa/bbbb/?ccc 652781344055627776

第四次CCF计算机软件能力认证

第一题:图像旋转 旋转是图像处理的基本操作,在这个问题中,你需要将一个图像逆时针旋转 90 度。 计算机中的图像表示可以用一个矩阵来表示,为了旋转一个图像,只需要将对应的矩阵旋转即可。 输入格式 输入的第一行包含两…

我国版式文档格式OFD前端WEB展示之EasyOFD

EasyOFD an ofd file web shower 一个在web端展示ofd文件的控件,该控件基于CANVAS绘制。 该控件使用了以下外部程序 1)jszip:解决解压文件。 2)x2js: 解决XML文件到JS转换 3)easyjbig2: 解决ofd内部使用jb2文件存储的…

NSSCTF刷web(2)

[NISACTF 2022]bingdundun~ bingdundun处感觉像文件包含,改upload为index 发现确实,猜测会补一个后缀.php 那常规文件包含都不行了,这里还有一个文件上传的功能,考虑phar协议 <?php$phar new Phar("test.phar"); $phar->startBuffering(); $phar->setStu…

【excel细碎小知识点】

目录索引 &符号的用法&#xff1a;实例演示&#xff1a; 数字显示和位数的区别&#xff1a;分列功能的妙用&#xff1a;什么叫做常规类型&#xff1a; &符号的用法&#xff1a; **连接字符串:**转化后都是文本字符串类型。你可以通过修改数据类型进行更多可能的操作 实…

【Go语言开发】简单了解一下搜索引擎并用go写一个demo

写在前面 这篇文章我们一起来了解一下搜索引擎的原理&#xff0c;以及用go写一个小demo来体验一下搜索引擎。 简介 搜索引擎一般简化为三个步骤 爬虫&#xff1a;爬取数据源&#xff0c;用做搜索数据支持。索引&#xff1a;根据爬虫爬取到的数据进行索引的建立。排序&#xf…

prometheus调整默认数据存储时间

调整kubernetes部署的prometheus数据存储时间 由于prometheus是用kuberentes部署的&#xff0c;没办法像传统部署方式那种直接在启动参数增加存储时间的参数。需要在configmap里或者在deployment里添加&#xff0c;我这里使用的方式是在deployement里添加调整存储时间的参数。…

学会在重装系统前如何备份软件,再也不怕失去珍贵的应用!

​Windows系统是电脑的重要组成部分&#xff0c;它不仅提供了友好的用户界面&#xff0c;还承担着许多关键的功能和任务&#xff0c;为我们提供了一个稳定、安全和效率的工作环境&#xff0c;使我们能够充分发挥电脑的潜力&#xff0c;优化工作效率和生活品质。 随着系统使…

为 GitHub 设置 SSH 密钥

1. 起因 给自己的 github 改个名&#xff0c;顺便就给原来 Hexo 对应的仓库也改了个名。然后发现 ubhexo clean && hexo generate && hexo deploy 失败了&#xff0c;报错如下&#xff1a; INFO Deploying: git INFO Clearing .deploy_git folder... INFO …

软件渗透测试真的很重要吗?渗透测试有哪些测试流程?

软件渗透测试是指通过模拟恶意攻击者的行为&#xff0c;评估软件系统中的潜在安全漏洞和弱点的活动。这种安全测试方法能够帮助开发人员和系统管理员发现并修复潜在的安全漏洞&#xff0c;以确保软件系统的安全性和完整性。软件渗透测试是一项高度技术性的任务&#xff0c;需要…

如何使用MATLAB软件完成生态碳汇涡度相关监测与通量数据分析

MATLAB MATLAB是美国MathWorks公司出品的商业数学软件&#xff0c;用于数据分析、无线通信、深度学习、图像处理与计算机视觉、信号处理、量化金融与风险管理、机器人&#xff0c;控制系统等领域。 [1] MATLAB是matrix&laboratory两个词的组合&#xff0c;意为矩阵工厂&a…