Node 之 Stream 深度剖析:从原理到项目实战应用场景全解

news2025/1/11 13:17:40

Node.js 中的 Stream

在 Node.js 中,Stream 是处理数据的抽象接口,尤其适用于处理大块数据流,而不是一次性加载整个数据。它提供了对数据的流式读写操作,可以帮助我们高效地处理 I/O 操作,比如文件读写、HTTP 请求、数据库交互等。

Stream 的基本类型
  1. Readable Stream(可读流):数据可以从流中读取。常见的可读流包括文件读取、HTTP 请求流、数据库查询等。

  2. Writable Stream(可写流):数据可以写入流中。常见的可写流包括文件写入、HTTP 响应流等。

  3. Duplex Stream(双工流):既可以读取,也可以写入。常见的双工流包括网络通信、双向数据流等。

  4. Transform Stream(转换流):是特殊类型的双工流,可以在读写过程中对数据进行转换。常见的如压缩、加密等操作。

为什么使用 Stream
  1. 内存高效:Stream 避免一次性将大数据加载到内存中,而是分块读取和写入数据,减少了内存的消耗。

  2. 性能更高:在处理大量数据时,Stream 允许数据一边读取一边处理,从而提高了性能和响应速度。

  3. 流式操作:通过事件驱动的方式来处理数据的读写,避免了阻塞,使得 Node.js 在高并发情况下仍能保持高效。

Stream 的基本操作

Stream 操作有很多常见的 API,可以通过事件监听器来控制数据流的流动:

  • stream.read():从流中读取数据。
  • stream.write():向流中写入数据。
  • stream.pipe():将一个可读流与一个可写流连接起来。

Stream 的应用场景

  1. 文件读取和写入:在处理大文件时,直接读取文件的全部内容会占用大量内存,而使用 Stream 可以逐步读取文件,降低内存使用。

  2. HTTP 请求和响应:在 Web 应用中,Stream 用于处理请求体和响应体的数据流。这样可以在接收到请求数据时就开始处理,而不必等待整个请求体被读取完成。

  3. 数据转换:通过 Transform Stream 可以实现数据的转码、压缩、加密等操作。比如,将数据压缩成 gzip 格式再发送给客户端。

  4. 实时数据处理:适合用于实时数据流,比如 WebSocket、日志处理、传感器数据等。

实际项目中的 Stream 使用示例

下面通过一个文件操作的示例来展示如何使用 Node.js 中的 Stream:

示例 1:文件读取与写入

假设我们需要读取一个大的文本文件,并将其内容转换成大写后写入另一个文件中。

const fs = require('fs');

// 创建可读流
const readableStream = fs.createReadStream('largeFile.txt', 'utf8');

// 创建可写流
const writableStream = fs.createWriteStream('outputFile.txt');

// 使用转换流进行大写转换
const transformStream = require('stream').Transform({
  transform(chunk, encoding, callback) {
    // 将数据转换为大写
    this.push(chunk.toString().toUpperCase());
    callback();
  }
});

// 将流连接起来:读取 -> 转换 -> 写入
readableStream
  .pipe(transformStream)   // 使用转换流进行数据转换
  .pipe(writableStream);    // 将转换后的数据写入文件

readableStream.on('end', () => {
  console.log('文件转换完成!');
});
解释:
  • fs.createReadStream():创建一个可读流,用于读取大文件。
  • fs.createWriteStream():创建一个可写流,用于将数据写入输出文件。
  • stream.Transform:自定义一个转换流,将读取到的数据转为大写。
  • pipe():将数据从一个流流向另一个流。在这里,我们将可读流的输出通过转换流再传递给可写流。

通过 pipe() 方法,我们可以串联多个流,使得数据从一个流到另一个流进行处理,避免了将整个文件一次性加载到内存中的问题,从而提高了效率。

示例 2:HTTP 请求和响应使用 Stream

在 Web 应用中,我们经常需要处理 HTTP 请求和响应体的流。以下是一个简单的示例,展示如何使用 Stream 从客户端请求中读取数据并处理:

const http = require('http');

const server = http.createServer((req, res) => {
  let data = '';

  // 将请求的 Body 数据流式读取并拼接
  req.on('data', chunk => {
    data += chunk;
  });

  req.on('end', () => {
    console.log('接收到的请求数据:', data);
    
    // 将处理后的数据响应回客户端
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('数据已处理');
  });

  req.on('error', err => {
    console.error('请求出错:', err);
    res.writeHead(500, { 'Content-Type': 'text/plain' });
    res.end('服务器错误');
  });
});

server.listen(3000, () => {
  console.log('服务器运行在 http://localhost:3000');
});
解释:
  • req.on('data', ...):监听请求的 data 事件,读取请求体中的数据。
  • req.on('end', ...):监听请求的 end 事件,处理完整的数据。
  • res.writeHead()res.end():分别用于设置响应头和发送响应。

这种方式非常适合处理 POST 请求,尤其是上传大文件或大量数据时,可以逐步处理请求体数据,而不必一次性将所有数据加载到内存中。

总结

  • Stream 是 Node.js 中处理数据流的核心,适用于需要处理大量数据或需要分块处理数据的场景。
  • 应用场景:文件读取与写入、HTTP 请求与响应、数据转换、实时数据处理等。
  • 优点:减少内存消耗,避免阻塞,提高性能。

通过流式处理,Node.js 可以高效地处理大规模 I/O 操作,保持非阻塞的优势,并且适应高并发的场景。

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

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

相关文章

加速物联网HMI革命,基于TouchGFX的高效GUI显示方案

TouchGFX 是一款针对 STM32 微控制器优化的先进免费图形软件框架。 TouchGFX 利用 STM32 图形功能和架构,通过创建令人惊叹的类似智能手机的图形用户界面,加速了物联网 HMI 革命。 TouchGFX 框架包括 TouchGFX Designer (TouchGFXDesigner)(…

Java-数据结构-栈与队列(StackQueue)

一、栈(Stack) ① 栈的概念 栈是一种特殊的线性表,它只允许固定一端进行"插入元素"和"删除元素"的操作,这固定的一端被称作"栈顶",对应的另一端就被称做"栈底"。 📚 栈中的元素遵循后…

案例研究:UML用例图中的结账系统

在软件工程和系统分析中,统一建模语言(UML)用例图是一种强有力的工具,用于描述系统与其用户之间的交互。本文将通过一个具体的案例研究,详细解释UML用例图的关键概念,并说明其在设计结账系统中的应用。 用…

【动态规划篇】欣赏概率论与镜像法融合下,别出心裁探索解答括号序列问题

本篇鸡汤:没有人能替你承受痛苦,也没有人能拿走你的坚强. 欢迎拜访:羑悻的小杀马特.-CSDN博客 本篇主题:带你解答洛谷的括号序列问题(绝对巧解) 制作日期:2025.01.10 隶属专栏:C/C题…

点击底部的 tabBar 属于 wx.switchTab 跳转方式,目标页面的 onLoad 不会触发(除非是第一次加载)

文章目录 1. tabBar 的跳转方式2. tabBar 跳转的特点3. 你的配置分析4. 生命周期触发情况5. 总结 很多人不明白什么是第一次加载,两种情况讨论,第一种情况假设我是开发者,第一次加载就是指点击微信开发者工具上边的编译按钮,每点击…

CUDA、CUDNN以及tensorRT的版本对应关系

各版本的对应除了可以看文件的命名上还可以查看TensorRT的Release日志: Release Notes :: NVIDIA Deep Learning TensorRT Documentation 这个是官方测试TensorRT的Release日志,里面指明了当前测试的TensorRT版本是在哪个CUDNN等库下的测试结果&#x…

设计模式(观察者模式)

设计模式(观察者模式) 第三章 设计模式之观察者模式 观察者模式介绍 观察者模式(Observer Design Pattern) 也被称为发布订阅模式 。模式定义:在对象之间定义一个一对多的依赖,当一个对象状态改变的时候…

Helm部署activemq

1.helm create activemq 创建helm文件目录 2.修改values.yaml 修改image和port 3. helm template activemq 渲染并输出 4. helm install activemq activemq/ -n chemical-park // 安装 5.启动成功

Untiy中如何嵌入前端页面,从而播放推流视频?

最近工作中频繁用到unity,虽然楼主之前也搞过一些UNTY游戏开发项目,但对于视频这块还是不太了解,所以我们采用的方案是在Unity里寻找一个插件来播放推流视频。经过我的一番寻找,发现了这款Vuplex 3D WebView,它可以完美的打通Unit…

rabbitmq的三个交换机及简单使用

提前说一下,创建队列,交换机,绑定交换机和队列都是在生产者。消费者只负责监听就行了,不用配其他的。 完成这个场景需要两个服务哦。 1直连交换机-生产者的代码。 在配置类中创建队列,交换机,绑定交换机…

Excel 技巧07 - 如何计算到两个日期之间的工作日数?(★)如何排除节假日计算两个日期之间的工作日数?

本文讲了如何在Excel中计算两个日期之间的工作日数,以及如何排除节假日计算两个日期之间的工作日数。 1,如何计算到两个日期之间的工作日数? 其实就是利用 NETWORKDAYS.INTL 函数 - weekend: 1 - 星期六,星期日 2,如…

初学stm32 --- DAC模数转换器工作原理

目录 什么是DAC? DAC的特性参数 STM32各系列DAC的主要特性 DAC框图简介(F1/F4/F7) 参考电压/模拟部分电压 触发源 关闭触发时(TEN0)的转换时序图 DMA请求 DAC输出电压 什么是DAC? DAC,全称:Digital…

从预训练的BERT中提取Embedding

文章目录 背景前置准备思路利用Transformer 库实现 背景 假设要执行一项情感分析任务,样本数据如下 可以看到几个句子及其对应的标签,其中1表示正面情绪,0表示负面情绪。我们可以利用给定的数据集训练一个分类器,对句子所表达的…

从CentOS到龙蜥:企业级Linux迁移实践记录(系统安装)

引言: 随着CentOS项目宣布停止维护CentOS 8并转向CentOS Stream,许多企业和组织面临着寻找可靠替代方案的挑战。在这个背景下,龙蜥操作系统(OpenAnolis)作为一个稳定、高性能且完全兼容的企业级Linux发行版&#xff0…

车联网安全--TLS握手过程详解

目录 1. TLS协议概述 2. 为什么要握手 2.1 Hello 2.2 协商 2.3 同意 3.总共握了几次手? 1. TLS协议概述 车内各ECU间基于CAN的安全通讯--SecOC,想必现目前多数通信工程师们都已经搞的差不多了(不要再问FvM了);…

iOS实际开发中使用Alamofire实现多文件上传(以个人相册为例)

引言 在移动应用中,图片上传是一个常见的功能,尤其是在个人中心或社交平台场景中,用户经常需要上传图片到服务器,用以展示个人风采或记录美好瞬间。然而,实现多图片上传的过程中,如何设计高效的上传逻辑并…

基于phpstudy快速搭建本地php环境(Windows)

好好生活,别睡太晚,别爱太满,别想太多。 2025.1.07 声明 仅作为个人学习使用,仅供参考 对于CTF-Web手而言,本地PHP环境必不可少,但对于新手来说从下载PHP安装包到配置PHP环境是个非常繁琐的事情&#xff0…

ffmpeg 编译遇到的坑

makeinfo: error parsing ./doc/t2h.pm: Undefined subroutine &Texinfo::Config::set_from_init_file called at ./doc/t2h.pm line 24. 编译选项添加: --disable-htmlpages

Git:merge合并、冲突解决、强行回退的终极解决方案

首先还是得避免冲突的发生,无法避免时再去解决冲突,避免冲突方法: 时常做pull、fatch操作,不要让自己本地仓库落后太多版本;在分支操作,如切换分支、合并分支、拉取分支前,及时清理Change&#…

国内外网络安全政策动态(2024年12月)

▶︎ 1.2项网络安全国家标准获批发布 2024年12月6日,根据2024年11月28日国家市场监督管理总局、国家标准化管理委员会发布的中华人民共和国国家标准公告(2024年第29号),全国网络安全标准化技术委员会归口的2项网络安全国家标准正…