【第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次…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...
