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) => {
            // 如果用户监听了 data
            if (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"); // 16k

let 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);

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

苹果平板电容笔好用吗?第三方apple pencil推荐

自从苹果推出了ipad的电容笔之后,一直在市场上保持着十分火爆的热度,但是因为Apple Pencil的价格太高,一般的消费者根本没有足够预算去入手。所以市场上就不断涌现出了不少可以很好代替Apple Pencil的平替电容笔,并且深受人们的热…

Word 插件实现读取excel自动填写

日常工作中碰到需要将EXCEL的对应数据记录填写到word文档对应的位置,人工操作的方式是: 打开exel表—>查找对应报告号的行—>逐列复制excel表列单元格内容到WORD对应的位置(如下图标注所示) 这种方法耗时且容易出错。实际上…

精选了6款好用的AI绘画工具,值得一试

近几年来,伴随着AI技术的发展,设计领域发生了巨大的变化。AI绘图工具的出现很大程度上减轻了设计师的工作负担,本文精选了6款优秀的AI绘图工具为大家推荐,一起来看看吧! 1、即时灵感 即时灵感作为国产的AI绘图工具&a…

java导出pdf(纯代码实现)

java导出pdf 在项目开发中,产品的需求越来越奇葩啦,开始文件下载都是下载为excel的,做着做着需求竟然变了,要求能导出pdf。导出pdf倒也不是特别大的问题关键就是麻烦。 导出pdf我知道的一共有3中方法: 方法一&#xff…

Spring Batch之读数据库—JdbcCursorItemReader之自定义PreparedStatementSetter(三十八)

一、自定义PreparedStatementSetter 详情参考我的另一篇博客: Spring Batch之读数据库——JdbcCursorItemReader(三十五)_人……杰的博客-CSDN博客 二、项目实例 1.项目实例 2.代码实现 BatchMain.java: package com.xj.dem…

只需一个提示词解除GPT-4的字符限制!

ChatGPT的内存有限,GPT-3.5-turbo的限制为4897个令牌,而GPT-4的最大限制为8192。如果您在使用GPT-4进行聊天时超过8192个令牌(约6827个单词),它就会开始遗忘。我想出了一种新的技巧,可以轻松将对话扩展10倍。 这种技巧不会将对话中的每个字都保存到内存中。当您去开会时,会有人…

同比环比数据可视化

引言 数据分析和可视化在现代商业环境中变得越来越重要。随着数据的迅速增长,我们需要有效的工具来解释和理解这些数据。 数据可视化提供了一种直观的方式,帮助我们从海量数据中提取有意义的见解,以支持业务决策。 同比环比图作为一种常见的…

C#鼠标拖拽,移动图片实例

最近工作需要做一个鼠标可以拖拽移动图片的功能。 写了几个基本功能,勉强能用。这里记录一下。欢迎大神补充。 这个就是完成的功能。 下边的绿色是一个pictureBox,白色框也是一个pictureBox,他们二者是子父级关系。 绿色是父级&#xff0c…

selenium查找svg元素

目录 如何为SVG元素编写XPath 使用local-name()的语法 需要记住的一点 将“and”与SVG元素一起使用 如何定位嵌套的SVG元素? XPath是一种用于定位XML文档中的web元素的语言,包括构成网页的HTML文档。在Selenium中&#xff0…

如何使用自动化构造随机路由模型

为什么要仿真随机路由? 路由器测试中,为了最大程度还原现网路由情况,评估路由器在现网环境下稳定工作各项指标,需要对导入路由进行离散仿真,目前路由仿真可分为导入路由与生成路由两种方式,导入路由需要现…

ceph对象存储和安装dashborad

一、ceph–RadosGW对象存储 数据不需要放置在目录层次结构中,而是存在于平面地址空间内的同一级别; 应用通过唯一地址来识别每个单独的数据对象; 每个对象可包含有助于检索的元数据; 在Ceph中的对象存储网关中,通过RESTful API在…

Stable Diffusion + EbSynth + ControlNet 解决生成视频闪烁

一、安装 1.1、安装ffmpeg 下载地址: 解压,配置环境变量 E:\AI\ffmpeg\bin 检查是否安装成功 1.2、安装SD的 EbSynth 插件 插件地址 https://github.com/s9roll7/ebsynth_utility 报错:ModuleNotFoundError: No module named extension…

降级npm后,出现xxx 不是内部或外部命令解决方法

比如我安装了anyproxy npm install anyproxy -g 之后在cmd中输入anyproxy 发现 anyproxy 不是内部或外部命令解决方法. 一般出现这样的问题原因是npm安装出现了问题,全局模块目录没有被添加到系统环境变量。 Windows用户检查下npm的目录是否加入了系统变量P…

短视频矩阵系统源码--开发实践

短视频矩阵系统源码开发技术: 1. 数据采集:使用Python的requests库进行数据爬取,使用Selenium模拟浏览器操作,解决抖音反爬虫机制。 2. 数据处理:使用Python的正则表达式、BeautifulSoup等库进行数据处理。 3. 关键…

【论文解读】2017 STGCN: Spatio-Temporal Graph Convolutional Networks

一、简介 使用历史速度数据预测未来时间的速度。同时用于序列学习的RNN(GRU、LSTM等)网络需要迭代训练,它引入了逐步累积的误差,并且RNN模型较难训练。为了解决以上问题,我们提出了新颖的深度学习框架STGCN,用于交通预测。 二、…

Unity 多相机 同屏显示

一 首先了解: 相机和Canvas 的渲染先后关系 什么是相机的渲染顺序? 答:简单理解就是 用毛刷 刷墙面,先刷的,会被后刷的 挡住 。 列如:相机01: 先渲染的大海,相机02:后…

如何使用DiskPart命令行格式化分区?

想要格式化磁盘分区,您可以使用磁盘管理工具,或在Windows文件资源管理器中右键单击驱动器并选择“格式化”。如果您更想使用命令行来格式化磁盘,那么Windows自带的DiskPart将是首选。 DiskPart有很多优点,例如,如果您想…

PyTorch 1.13简介

# 1.  PyTorch 1.13 据官方介绍,PyTorch 1.13 中包括了 BetterTransformer 的稳定版,且不再支持 CUDA 10.2 及 11.3,并完成了向 CUDA 11.6 及 11.7 的迁移。此外 Beta 版还增加了对 Apple M1 芯片及 functorch 的支持。 1.1 主要更新 Be…

Java虚拟机——字节码指令简介

Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码) 以及 跟随其后的零至多个代表此操作所需的参数(称为操作数)构成。大多数指令都不包括操作数,只有一个操作码,指令参数都存放…

【云原生】k8s安全机制

前言 Kubernetes 作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务。API Server 是集群内部各个组件通信的中介, 也是外部控制的入口。所以 Kubernetes 的安全机制基本就是围绕保护 API Server 来设计的。 比如 kubectl 如果想向 API…