【第2章 Node.js基础】2.7 Node.js 的流(一) 可读流
🌈 Node.js 的流
🚀什么是流
流不是 Node.js 特有的概念。它们是几十年前在 Unix 操作系统中引入的。
我们可以把流看作这些数据的集合,就像液体一样,我们先把这些液体保存在一个容器里(流的内部缓冲区 BufferList),等到相应的事件触发的时候,我们再把里面的液体倒进管道里,并通知其他人在管道的另一侧拿自己的容器来接里面的液体进行处理。

Node.js中的流是一种处理数据的抽象接口,它提供了一种有效的方式(按需处理数据)来读取或写入大量数据,而无需一次性将整个数据加载到内存中。流可以被视为数据在某段时间内从一个点移动到另一个点的序列,类似于水从一根管子的一端流到另一端。
🚀Node.js流的好处
Node.js流解决了处理大量数据时可能遇到的内存消耗和性能问题。以下是使用Node.js流的好处:
-
内存效率:使用流可以按需处理数据,而不需要一次性将整个数据加载到内存中。这意味着即使处理大量数据,也可以节省大量的内存空间。流以块的形式处理数据,每次只加载和处理一小部分数据,然后将其释放,从而减少了内存的使用量。
-
性能优化:由于流以块的形式处理数据,可以实现并行处理,提高处理速度。流还可以通过流水线(pipeline)的方式将多个操作连接起来,实现数据的连续处理,从而提高整体性能。
-
响应性:使用流可以实现实时处理数据,即在数据到达时立即进行处理,而不需要等待整个数据加载完成。这对于需要实时处理数据的应用程序非常重要,例如实时日志分析、实时聊天等。
-
可扩展性:流是可组合的,可以将多个流连接起来形成更复杂的数据处理流程。这种可组合性使得代码更加模块化和可重用,便于扩展和维护。
-
适用于各种场景:Node.js流可以用于处理各种类型的数据,包括文件、网络请求、数据库查询结果等。无论是处理大文件、处理网络请求还是处理数据库查询结果,使用流都可以提供高效的数据处理方式。
🚀Node.js流的重点知识
以下是关于Node.js流的重点知识点总结:
- 流的类型:流可以是可读的、可写的,或者可读可写的。在Node.js中,有四种内置的流类型,
- 可读流(Readable)、
- 可写流(Writable)、
- 双工流(Duplex)
- 转换流(Transform)。
- 常见的流事件:所有的流都是EventEmitter类的实例,可以通过事件和方法来处理流的数据。
- data(当有数据可读时触发)、
- end(当没有更多数据可读时触发)
- error(当发生错误时触发)等。
- 常见的流方法包括
- write(向流中写入数据)
- read(从流中读取数据)
- pipe(将一个可读流的数据传输到一个可写流)等。
- 流的工作原理:流将要传输的数据处理成连续的块(chunk),通过一小块一小块地传输数据,从而降低内存消耗并提高性能。这种逐段处理的方式使得流非常适合处理大量数据或需要逐段处理的场景。
- 内置的流对象:Node.js中有许多内置的流对象,如HTTP请求、文件读写、标准输入输出(stdin/stdout)等。这些内置的流对象可以直接使用,无需直接实现流的接口。
- stream模块:stream模块是用于构建实现流接口的对象的模块,可以通过
require('stream')导入。开发人员可以使用stream模块创建自定义的流实例,实现更复杂的流操作。
🌈 可读流
🚀什么是可读流
可读流是对提供数据的来源的一种抽象。可读流的例子包括客户端的 HTTP 响应、服务器的 HTTP请求、fs 的读取流、zlib 流、crypto 流、TCP Socket、子进程 stdout与stderr、process.stdin 等。所有可读流都实现了 stream.Readable 类定义的接口。
fs读取文件案例
文件:fs读取文件.js
const fs = require("fs");
// 创建可读流
const rs = fs.createReadStream("./movie.txt");let content = "";
// 当有数据可读时触发"data"事件
rs.on("data", chunk => {// 将读取的数据块拼接到content变量中content += chunk;
});// 当可读流结束时触发"end"事件
rs.on("end", () => {// 所有数据已读取完毕,输出content内容console.log(content);
});
文件:movie.txt
The best time to plant a tree is 20 years ago.
The second-best time is now.
种一棵树最好的时间是20年前,
其次是现在
输出结果
PS D:\WuWorkSpace\code\NodejsProject\nodejs实战学习\【第2章 Node.js基础】\2.7 Node的流> node .\fs可读流.js
The best time to plant a tree is 20 years ago.
The second-best time is now.
种一棵树最好的时间是20年前,
其次是现在
process.stdin案例
process.stdin.pipe(process.stdout);
这段代码使用了Node.js的process.stdin和process.stdout流对象,并通过pipe方法将输入流(process.stdin)的数据直接传输到输出流(process.stdout)中。
具体解析如下:
process.stdin是一个可读流,它表示标准输入流(stdin),可以用于接收用户的输入。process.stdout是一个可写流,它表示标准输出流(stdout),可以用于向控制台输出数据。
通过调用pipe方法,我们将输入流(process.stdin)连接到输出流(process.stdout),这样输入流中的数据会被自动传输到输出流中。
这段代码的作用是将用户在控制台输入的内容直接输出到控制台,实现了一个简单的输入输出的管道(复读机)。
动图演示如下

http案例
客户端的 HTTP 响应、服务器的 HTTP请求是可读流。
服务端文件:http-server.js
const http = require("http");
const server = http.createServer((req,res)=>{if(req.method === "POST" && req.url.includes("/upload")){process.stdout.write("服务端收到了请求:");// req 服务器的 HTTP 请求(可读流)req.pipe(process.stdout);// res 服务器的 HTTP 响应(可写流)res.write("我是服务端响应");res.end();}else{res.writeHead(404);res.end("Not Found");}
})
server.listen(9800);
console.log(`服务已经运行在:http://localhost:9800`);
客户端代码文件:http-client.js
const http = require("http");
const options = {hostname : "127.0.0.1",port : 9800,path : "/upload",method : "POST"
};
const req = http.request(options,res=>{process.stdout.write("客户端获取响应:");// res 客户端的 HTTP 响应(可读流)res.pipe(process.stdout);
})// req 客户端的 HTTP 请求(可写流)
req.write("我是客户端。");
req.end();
以下是运行演示:先运行服务端代码 http-server.js ,再运行客户端代码http-client.js。
$ node .\http-client.js
客户端获取响应:我是服务端响应
$ node .\http-server.js
服务已经运行在:http://localhost:9800
服务端收到了请求:我是客户端。
··
🚀可读流de两种模式
可读流有两种模式:流动(Flowing)和暂停(Paused )。在流动模式中,数据被自动从底层系统读取,并通过 EventEmitter 接口的事件尽可能快地提供给应用程序。在暂停模式中,必须显式调用stream.read()方法读取数据块。
所有可读流一开始都处于暂停模式,,之后可以通过以下方式切换到流动模式。
- 添加data 事件处理函数。
- 调用stream.resume()方法。
- 调用 stream.pipe()方法。
可读流也可以通过以下方式切换回暂停模式。
- 如果没有管道目标,则调用 stream.pause()方法
- 如果有管道目标,则移除所有管道目标。调用 stream.unpipe()方法可以移除多个管道目标。
注意 👉: 只有提供了数据消费或忽略数据的机制后,可读流才会产生数据。如果消费的机制被禁用或移除,则可读流会停止产生数据。
stream.Readable类定义的主要事件:
- data:当有数据可读时被触发。
- end:没有更多的数据可读时被触发。
- close:当流或其底层资源被关闭时被触发。
stream.Readable 类定义的主要方法
- readable.read([size]):从内部缓冲区拉取并返回数据。
- readable.pause():使流动模式的流停止触发data事件,并切换出流动模式。
- readable.setEncoding(encoding):为从可读流读取的数据设置字符编码。
相关文章:
【第2章 Node.js基础】2.7 Node.js 的流(一) 可读流
🌈 Node.js 的流 🚀什么是流 流不是 Node.js 特有的概念。它们是几十年前在 Unix 操作系统中引入的。 我们可以把流看作这些数据的集合,就像液体一样,我们先把这些液体保存在一个容器里(流的内部缓冲区 BufferList&…...
Ubuntu/Debian Hat 系 Linux 使用
目录 1. Ubuntu/Debian Hat 系 Linux 使用1.1. 包1.1.1. Install Package1.1.2. Convert .rpm package to .deb1.1.3. Install RPM Package Directly Onto the System on Ubuntu 1. Ubuntu/Debian Hat 系 Linux 使用 1.1. 包 1.1.1. Install Package dpkg -i <name of pa…...
php接口api数据签名及验签
api数据签名作用:通过使用签名可以验证数据在传输过程中是否被篡改或修改。接收方可以使用相同的签名算法和密钥对接收到的数据进行验证,如果验证失败则表明数据被篡改过 1、数据发送方进行接口签名并传输签名字段 <?php // 请求URL $url "h…...
实战:给docusaurus文档网站配置Algolia 实现全站内容搜索功能-2023.11.16(已解决)
更新于:2023年11月16日 次文档已全部脱敏! 实战:给docusaurus文档网站配置Algolia 实现全站内容搜索功能-2023.11.16(已解决) 目录 前提条件 🍀 前提条件 具备docker环境 具有自己的网站 🍀 实验软件(…...
Ubuntu18.04安装ROS系统+turtle测试
安装 1.设置安装源 sudo sh -c echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list sudo sh -c . /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubun…...
UE基础篇五:动画
导语: 视频文档在文末 一、动画 1.1 物理资产可以用来做布娃娃系统 1.2 混合空间 调整这个值会在动画切换时有一个插值时间,表现为等一下再切 1.3 启用根运动 1.4 一些导入设置只有在导入时才有效, 1.5 动画图标可以预览调节数值<...
SELinux零知识学习十二、SELinux策略语言之客体类别和许可(6)
接前一篇文章:SELinux零知识学习十一、SELinux策略语言之客体类别和许可(5) 一、SELinux策略语言之客体类别和许可 3. 有效的客体类别 (3)System V IPC客体队列 与IPC有关的客体类别代表System V IPC资源。下表总结…...
vscode的git 工具使用
vscode的git 工具使用 目录概述需求: 设计思路实现思路分析1.git 工具的使用2.提交代码3.查看历史提交代码 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a be…...
利用回溯绕过正则表达式
目录 利用strpos的特性拿到flag 利用回溯绕过正则表达式 利用回溯次数绕过正则表达式并且实现文件上传 使用回溯绕过正则表达式waf拿到flag 本篇会讲解三个实验来分别绕过正则表达式,python的正则表达式和Javascript的正则表达式大致相同如果有正则表达式不太懂…...
Flutter执行flutter doctor报错HTTP Host Availability
问题描述 [!] HTTP Host Availability✗ HTTP host https://maven.google.com/ is not reachable. Reason: An erroroccurred while checking the HTTP host: Operation timed out解决方案 将文件flutter/packages/flutter_tools/lib/src/http_host_validator.dart中的https:…...
全栈工程师必须要掌握的前端Html技能
作为一名全栈工程师,在日常的工作中,可能更侧重于后端开发,如:C#,Java,SQL ,Python等,对前端的知识则不太精通。在一些比较完善的公司或者项目中,一般会搭配前端工程师&a…...
腾讯云服务器租用价格,腾讯云服务器租用价格多少钱一年?
腾讯云服务器租用价格,腾讯云服务器租用价格多少钱一年?腾讯云服务器有优惠活动,现在租用只需要88元/年!腾讯云服务器优惠购买入口:https://1111.mian100.cn 随着互联网的发展,越来越多的人开始选择将自己…...
QTableWidget 设置列宽行高大小的几种方式及其他常用属性设置
目录 效果: 1.列宽、行高自动分配 2.固定值 3.随内容分配列宽 随内容分配行高 4.水平方向标签拓展剩下的窗口部分,填满表格 5.列宽是自动分配的,但是第一列可手动调整宽度,而表格整体的列宽仍是自动分配的。第二、三列办法调…...
【AI视野·今日CV 计算机视觉论文速览 第277期】Fri, 27 Oct 2023
AI视野今日CS.CV 计算机视觉论文速览 Fri, 27 Oct 2023 Totally 93 papers 👉上期速览✈更多精彩请移步主页 Daily Computer Vision Papers A Coarse-to-Fine Pseudo-Labeling (C2FPL) Framework for Unsupervised Video Anomaly Detection Authors Anas Al lahham…...
【教3妹学编程-算法题】购买物品的最大开销
3妹:2哥,听说你今天发工资啦? 请我吃饭怎么样,嘿嘿 2哥 : 切,你上周还发工资了呢,也没见你请我吃饭。 3妹:哎呀, 我的工资都用来双11 shopping了, 双11过后我都吃了1周土…...
关于pandas dataframe数据转换为JSON格式存储在Redis后,读取数据时发生数据篡改的问题以及解决办法
问题:当时处理股票数据,获取到以dataframe数据结构的股票,由于Redis 是一个内存中的数据结构存储系统,但是不接受dataframe数据结构的数据,选择将其先转化为JSON格式,但发现再将JSON格式转化为原数据时&…...
Go 语言编译环境
1. 请简要介绍一下Go语言的特点。 Go语言是一种静态类型、编译型语言,由Google开发。它的主要特点包括: 简洁高效:Go语言的语法非常简洁,易于学习和使用。同时,Go语言的执行效率高,适合开发高性能的后端服…...
Leetcode刷题详解——衣橱整理
1. 题目链接:LCR 130. 衣橱整理 2. 题目描述: 家居整理师将待整理衣橱划分为 m x n 的二维矩阵 grid,其中 grid[i][j] 代表一个需要整理的格子。整理师自 grid[0][0] 开始 逐行逐列 地整理每个格子。 整理规则为:在整理过程中&am…...
短视频ai剪辑分发账号矩阵系统(招商oem)----源头技术开发
短视频ai剪辑分发账号矩阵系统 1. 视频剪辑工具——原创短视频一键生成,视频剪辑亮点分析 (1)多模式智能剪辑 包含智能混剪逻辑、智能组合、场景顺序、图片生成视频等多种模式。在视频创作上也做了简化,即使是没有剪辑能力的创…...
Ubuntu18.04安装Loam保姆级教程
系统环境:Ubuntu18.04.6 LTS 1.Loam的安装前要求: 1.1 ROS安装:参考我的另一篇博客 Ubuntu18.04安装ROS-melodic保姆级教程_灬杨三岁灬的博客-CSDN博客还是那句话,有时候加了这行也不好使,我是疯狂试了20次…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
未授权访问事件频发,我们应当如何应对?
在当下,数据已成为企业和组织的核心资产,是推动业务发展、决策制定以及创新的关键驱动力。然而,未授权访问这一隐匿的安全威胁,正如同高悬的达摩克利斯之剑,时刻威胁着数据的安全,一旦触发,便可…...
Axure Rp 11 安装、汉化、授权
Axure Rp 11 安装、汉化、授权 1、前言2、汉化2.1、汉化文件下载2.2、windows汉化流程2.3、 macOs汉化流程 3、授权 1、前言 Axure Rp 11官方下载链接:https://www.axure.com/downloadthanks 2、汉化 2.1、汉化文件下载 链接: https://pan.baidu.com/s/18Clf…...
