【第2章 Node.js基础】2.7 Node.js 的流(一) 可读流

news2024/10/5 19:17:54

🌈 Node.js 的流

🚀什么是流

流不是 Node.js 特有的概念。它们是几十年前在 Unix 操作系统中引入的。

我们可以把流看作这些数据的集合,就像液体一样,我们先把这些液体保存在一个容器里(流的内部缓冲区 BufferList),等到相应的事件触发的时候,我们再把里面的液体倒进管道里,并通知其他人在管道的另一侧拿自己的容器来接里面的液体进行处理。

在这里插入图片描述

Node.js中的流是一种处理数据的抽象接口,它提供了一种有效的方式(按需处理数据)来读取或写入大量数据,而无需一次性将整个数据加载到内存中。流可以被视为数据在某段时间内从一个点移动到另一个点的序列,类似于水从一根管子的一端流到另一端。

🚀Node.js流的好处

Node.js流解决了处理大量数据时可能遇到的内存消耗和性能问题。以下是使用Node.js流的好处:

  1. 内存效率:使用流可以按需处理数据,而不需要一次性将整个数据加载到内存中。这意味着即使处理大量数据,也可以节省大量的内存空间。流以块的形式处理数据,每次只加载和处理一小部分数据,然后将其释放,从而减少了内存的使用量。

  2. 性能优化:由于流以块的形式处理数据,可以实现并行处理,提高处理速度。流还可以通过流水线(pipeline)的方式将多个操作连接起来,实现数据的连续处理,从而提高整体性能。

  3. 响应性:使用流可以实现实时处理数据,即在数据到达时立即进行处理,而不需要等待整个数据加载完成。这对于需要实时处理数据的应用程序非常重要,例如实时日志分析、实时聊天等。

  4. 可扩展性:流是可组合的,可以将多个流连接起来形成更复杂的数据处理流程。这种可组合性使得代码更加模块化和可重用,便于扩展和维护。

  5. 适用于各种场景:Node.js流可以用于处理各种类型的数据,包括文件、网络请求、数据库查询结果等。无论是处理大文件、处理网络请求还是处理数据库查询结果,使用流都可以提供高效的数据处理方式。

🚀Node.js流的重点知识

以下是关于Node.js流的重点知识点总结:

  1. 流的类型:流可以是可读的、可写的,或者可读可写的。在Node.js中,有四种内置的流类型,
    1. 可读流(Readable)、
    2. 可写流(Writable)、
    3. 双工流(Duplex)
    4. 转换流(Transform)。
  2. 常见的流事件:所有的流都是EventEmitter类的实例,可以通过事件和方法来处理流的数据。
    1. data(当有数据可读时触发)、
    2. end(当没有更多数据可读时触发)
    3. error(当发生错误时触发)等。
  3. 常见的流方法包括
    1. write(向流中写入数据)
    2. read(从流中读取数据)
    3. pipe(将一个可读流的数据传输到一个可写流)等。
  4. 流的工作原理:流将要传输的数据处理成连续的块(chunk),通过一小块一小块地传输数据,从而降低内存消耗并提高性能。这种逐段处理的方式使得流非常适合处理大量数据或需要逐段处理的场景。
  5. 内置的流对象:Node.js中有许多内置的流对象,如HTTP请求、文件读写、标准输入输出(stdin/stdout)等。这些内置的流对象可以直接使用,无需直接实现流的接口。
  6. 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.stdinprocess.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):为从可读流读取的数据设置字符编码。

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

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

相关文章

【Android】设置全局标题栏

序言 在做项目的时候,有时候需要一个全局统一的标题栏,保证项目风格的统一,但是如果在每个activity上面都写一遍这个标题栏就很麻烦了,我们经常用的方法就是写个基类Activity,然后当某个Activity需要这个统一的标题栏…

我记不住的getopt_long的那些参数和返回值

前言:最近在学习面向Linux系统进行C语言的编程,通过查询man手册和查看网络上的各种文章来获取一点点的知识,重点是看完手册还是一脸懵逼,搞不懂手册里面再说啥,而本篇文章将记录一下学习getopt_long的那些参数和返回值…

NFTScan 正式上线 Viction NFTScan 浏览器和 NFT API 数据服务

2023 年 11 月 16 号,NFTScan 团队正式对外发布了 Viction NFTScan 浏览器,将为 Viction 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。NFTScan 作为全球领先的 NFT 数据基础设施服务商,Viction 是继 Bitcoin、Ethereum、BN…

GUI编程--PyQt5--QTreeWidget

文章目录 树型控件展示数据修改节点数据获取所有节点的数据 Qt模组参考 QWidgets QTreeWidget 树型控件展示数据 展示数据的同时,每个节点标注数据类型。 class MyWindow(QWidget):def __init__(self, title):super(MyWindow, self).__init__()self.setWindowTitl…

qt笔记之qml和C++的交互系列(一):初记

code review! —— 杭州 2023-11-16 夜 文章目录 一.qt笔记之qml和C的交互:官方文档阅读理解0.《Overview - QML and C Integration》中给出五种QML与C集成的方法1.Q_PROPERTY:将C类的成员变量暴露给QML2.Q_INVOKABLE()或public slots:将C类…

【面试经典150 | 数学】回文数

文章目录 写在前面Tag题目来源题目解读解题思路方法一:反转一半数字 其他语言python3 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内容以分析题目为主,并附带一些对于本…

遵循开源软件安全路线图

毫无疑问,开源软件对于满足联邦任务所需的开发和创新至关重要,因此其安全性至关重要。 OSS(运营支持系统) 支持联邦政府内的每个关键基础设施部门。 联邦政府认识到这一点,并正在采取措施优先考虑 OSS 安全&#xff…

Android Jetpack的组件介绍,常见组件解析

jetpack组件有哪些 Android Jetpack是一个集成Android应用程序组件的一站式解决方案。它使开发人员能够专注于他们的应用程序的真正创新部分,而不会受到Android平台特定的限制。Jetpack组件可分为四个类别: 架构组件(Architecture Componen…

IDEA无法查看源码是.class,而不是.java解决方案?

问题:在idea中,ctrl鼠标左键进入源码,但是有时候会出现无法查看反编译的源码,如图! 而我们需要的是方法1: mvn dependency:resolve -Dclassifiersources 注意:需要该模块的目录下,不是该文件目…

STM32_SPI总线驱动OLED详细原理讲解

目录 这里写目录标题 第13章 Cortex-M4-SPI总线13.1 SPI总线概述13.1.1 SPI总线介绍13.1.2 SPI总线接口与物理拓扑结构13.1.3 SPI总线通信原理13.1.4 SPI总线数据格式 13.2 IO口模拟SPI操作OLED13.2.1 常见的显示设备13.2.2 OLED显示屏概述13.2.3 OLED特征13.2.4 显示原理13.2.…

stylelint报错at-rule-no-unknown

stylelint报错at-rule-no-unknown stylelint还将各种 sass -rules 标记mixin为include显示未知错误 at-rule-no-unknown ✖ stylelint --fix:Deprecation warnings: 78:1 ✖ Unexpected unknown at-rule "mixin" at-rule-no-unknown 112:3 ✖ Unexpected un…

第四章 串【24王道数据结构笔记】

1.串的基本概念 串,即字符串 (String) 是由零个或多个字符组成的有限序列。一般记为Sa1a2.....an(n>0) S"HelloWorld!" TiPhone 11 Pro Max? 其中,S是串名,单引号括起来的字符序列是串的值;a;可以是字母、数字或其他字符;串中…

DocCMS keyword SQL注入漏洞复现 [附POC]

文章目录 DocCMS keyword SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 DocCMS keyword SQL注入漏洞复现 [附POC] 0x01 前言 免责声明:请勿利用文章内的相关技术从事非法测…

idea中误删.iml和.idea文件,如何处理

目录 一、问题描述 二、解决方案 1、理论知识 (1).iml 文件 (2).idea文件 2、操作环境 3、操作步骤 (1)找到【Maven】工具按钮 (2)点图标,重复导入maven项目&am…

Pikachu漏洞练习平台之XXE(XML外部实体注入)

目录 什么是 XML? 什么是DTD? 什么是XEE? 常见payload 什么是 XML? XML 指可扩展标记语言(EXtensible Markup Language); XML 不会做任何事情,而是用来结构化、存储以及传输信息…

promise时效架构升级方案的实施及落地 | 京东物流技术团队

一、项目背景 为什么需要架构升级 promise时效包含两个子系统:内核时效计算系统(系统核心是时效计算)和组件化时效系统(系统核心是复杂业务处理以及多种时效业务聚合,承接结算下单黄金流程流量)&#xff…

SPASS-参数估计与假设检验

参数估计 点估计 点估计用样本统计量的值直接作为总体参数的估计值。如用样本均值直接作为总体均值的估计值,用样本方差直接作为总体方差的估计值等。 常用的点估计法 (1)矩估计法 (2)极大似然估计法 (3)稳健估计法 区间估计 因为点估计直接用样本估计值作为总体参数…

苹果MAC安装绿盾出现问题,安装时没有出现填服务器地址的页面,现在更改不了也卸载不了绿盾 怎么处理?

环境: Mac mini M1 Mac os 11.0 绿盾v6.5 问题描述: 苹果MAC安装绿盾出现问题,安装时没有出现填服务器地址的页面,现在更改不了也卸载不了绿盾 怎么处理? 解决方案: 大部分企业是Windows和Mac终端混合使用,在进行文档加密管理时通常会遇到不兼容的现象,而为了统一…

Ubuntu 18.04无网络连接的n种可能办法

文章目录 网络图标消失,Ubuntu无网络连接VMware上Ubuntu18.04,桥接了多个网卡,其中一个用来上网,均设置为静态ip网络桥接链路没有接对路由不对 网络图标消失,Ubuntu无网络连接 sudo service network-manager stop sud…

python趣味编程-5分钟实现一个谷歌恐龙游戏(含源码、步骤讲解)

Python 恐龙游戏是为想要学习 Python 的初学者创建的。该项目系统使用了 Pygame 和 Random 模块。 Pygame 是一组跨平台的 Python 模块,专为编写视频游戏而设计。 Python 中的 Dino Game有一个任务记录,其中包含图片文档和 Python 内容(dino.py)。 GUI 使用 pygame 库。