Node.js入门教程(十八):Stream(流)

发布时间:2026/10/8 14:14:11

Node.js入门教程(十八):Stream(流) 一、什么是 StreamNode.js 的 Stream 是一种处理流式数据的抽象接口广泛应用于文件操作、网络通信等场景。流式数据处理的一个主要优点是可以在数据传输过程中就开始处理数据而不需要等待整个数据加载完毕这使得 Node.js 能够高效地处理大量数据而不会占用过多的内存。Stream 是一个抽象接口Node 中有很多对象实现了这个接口。例如对 http 服务器发起请求的request对象就是一个 Stream还有stdout标准输出。Node.js 的 Stream流允许你以流的形式处理数据而不是一次性将数据全部加载到内存中。这对于处理大量数据或者实现高效的数据传输非常有用。二、流的四种类型类型说明Readable可读流可读操作如文件读取流、网络请求响应流Writable可写流可写操作如文件写入流、网络请求发送流Duplex双工流可读可写操作如 TCP 套接字Transform转换流操作被写入数据然后读出结果如压缩/解压缩流常用事件所有的 Stream 对象都是EventEmitter的实例。常用的事件有事件说明data当有数据可读时触发end没有更多的数据可读时触发error在接收和写入过程中发生错误时触发finish所有数据已被写入到底层系统时触发三、从流中读取数据常见的可读流包括文件读取流和网络请求响应流。创建input.txt文件内容如下地址www.chenbyte.com创建main.js文件代码如下var fs require(fs); var data ; // 创建可读流 var readerStream fs.createReadStream(input.txt); // 设置编码为 utf8 readerStream.setEncoding(UTF8); // 处理流事件 -- data, end, and error readerStream.on(data, function(chunk) { data chunk; }); readerStream.on(end, function() { console.log(data); }); readerStream.on(error, function(err) { console.log(err.stack); }); console.log(程序执行完毕);以上代码执行结果如下程序执行完毕 地址www.chenbyte.com四、写入流可写流用于将数据写入目的地常见的可写流包括文件写入流和网络请求发送流。创建main.js文件代码如下var fs require(fs); var data 菜鸟教程官网地址www.runoob.com; // 创建一个可以写入的流写入到文件 output.txt 中 var writerStream fs.createWriteStream(output.txt); // 使用 utf8 编码写入数据 writerStream.write(data, UTF8); // 标记文件末尾 writerStream.end(); // 处理流事件 -- finish、error writerStream.on(finish, function() { console.log(写入完成。); }); writerStream.on(error, function(err) { console.log(err.stack); }); console.log(程序执行完毕);以上程序会将data变量的数据写入到output.txt文件中。代码执行结果如下$ node main.js 程序执行完毕 写入完成。查看output.txt文件的内容$ cat output.txt 地址www.chenbyte.com五、双工流Duplex双工流同时具有可读和可写的能力。一个典型的双工流是 TCP 套接字。const net require(net); // 创建一个 TCP 服务器 const server net.createServer((socket) { console.log(Client connected.); // 读取客户端数据 socket.on(data, (data) { console.log(Received data:, data.toString()); }); // 向客户端发送数据 socket.write(Hello, Client!\n); // 监听关闭事件 socket.on(end, () { console.log(Client disconnected.); }); }); server.listen(3000, () { console.log(Server listening on port 3000.); });六、转换流Transform转换流是一种特殊的双工流可以修改或转换数据。常见的转换流包括压缩和解压缩流。const zlib require(zlib); const fs require(fs); // 创建一个可读流 const readableStream fs.createReadStream(example.txt); // 创建一个转换流压缩 const gzip zlib.createGzip(); // 创建一个可写流 const writableStream fs.createWriteStream(example.txt.gz); // 将可读流管道到转换流再管道到可写流 readableStream.pipe(gzip).pipe(writableStream); // 监听完成事件 writableStream.on(finish, () { console.log(File compressed successfully.); });七、管道流Pipe管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。把文件比作装水的桶而水就是文件里的内容我们用一根管子pipe连接两个桶使得水从一个桶流入另一个桶这样就慢慢实现了大文件的复制过程。管道流操作实例设置input.txt文件内容如下菜鸟教程官网地址www.chenbyte.com创建main.js文件代码如下var fs require(fs); // 创建一个可读流 var readerStream fs.createReadStream(input.txt); // 创建一个可写流 var writerStream fs.createWriteStream(output.txt); // 管道读写操作 // 读取 input.txt 文件内容并将内容写入到 output.txt 文件中 readerStream.pipe(writerStream); console.log(程序执行完毕);代码执行结果如下$ node main.js 程序执行完毕查看output.txt文件的内容$ cat output.txt 地址www.chenbyte.com八、链式流链式是通过连接输出流到另外一个流并创建多个流操作链的机制。链式流一般用于管道操作。接下来我们使用管道和链式来压缩和解压文件。压缩文件创建compress.js文件代码如下var fs require(fs); var zlib require(zlib); // 压缩 input.txt 文件为 input.txt.gz fs.createReadStream(input.txt) .pipe(zlib.createGzip()) .pipe(fs.createWriteStream(input.txt.gz)); console.log(文件压缩完成。);代码执行结果如下$ node compress.js 文件压缩完成。执行完以上操作后可以看到当前目录下生成了input.txt的压缩文件input.txt.gz。解压文件创建decompress.js文件代码如下var fs require(fs); var zlib require(zlib); // 解压 input.txt.gz 文件为 input.txt fs.createReadStream(input.txt.gz) .pipe(zlib.createGunzip()) .pipe(fs.createWriteStream(input.txt)); console.log(文件解压完成。);代码执行结果如下$ node decompress.js 文件解压完成。九、暂停和恢复可读流可以暂停和恢复数据的读取。const fs require(fs); const readableStream fs.createReadStream(example.txt, utf8); readableStream.on(data, (chunk) { console.log(Received chunk:, chunk); readableStream.pause(); // 暂停读取 setTimeout(() { readableStream.resume(); // 恢复读取 }, 1000); });十、销毁流可以销毁流释放资源。const fs require(fs); const readableStream fs.createReadStream(example.txt, utf8); readableStream.on(data, (chunk) { console.log(Received chunk:, chunk); readableStream.destroy(); // 销毁流 });十一、流的主要方法方法说明readable.pipe(destination)将可读流的数据传输到可写流readable.on(data, callback)监听数据事件readable.on(end, callback)监听结束事件readable.pause()暂停可读流readable.resume()恢复可读流readable.destroy()销毁可读流writable.write(chunk)写入数据到可写流writable.end()结束写入writable.on(finish, callback)监听写入完成事件writable.on(error, callback)监听错误事件十二、本章小结知识点说明Stream 是什么处理流式数据的抽象接口高效处理大量数据四种流类型Readable可读、Writable可写、Duplex双工、Transform转换常用事件data、end、error、finish管道流pipe()方法将可读流连接到可写流链式流多个pipe()串联形成处理链压缩/解压使用zlib模块配合转换流实现控制流pause()、resume()、destroy()控制流的行为提示Stream 是 Node.js 高效处理 I/O 的核心机制。对于大文件处理、网络数据传输等场景使用 Stream 可以显著降低内存占用提升应用性能。管道流pipe是 Stream 中最常用的操作模式可以简洁地将数据从源头传递到目的地。
延伸阅读

更多相关文章

2026/9/30 6:04:08

QGIS布局模板实战:提升GIS地图出图效率300%

1. QGIS布局模板核心价值解析在地理信息系统(GIS)工作中,地图出图是成果展示的关键环节。QGIS的布局模板功能相当于设计师的样式库,能让我们快速复用成熟的版式设计。预设模板是软件自带的"标准答案",而自定…

2026/10/5 10:21:07

终极指南:免费将图片转换为3D打印模型的ImageToSTL工具

终极指南:免费将图片转换为3D打印模型的ImageToSTL工具 【免费下载链接】ImageToSTL This tool allows you to easily convert any image into a 3D print-ready STL model. The surface of the model will display the image when illuminated from the left side.…

2026/10/7 11:29:34

Ubuntu 22.04 Samba文件共享服务搭建与配置全指南

1. 项目概述:为什么要在Ubuntu上搭建Samba?如果你手头有一台安装了Ubuntu 22.04的电脑,无论是作为主力开发机、家庭服务器,还是淘汰旧笔记本改造的NAS,让它和家里的Windows电脑、Mac或者手机共享文件,总是一…

2026/10/8 16:01:47

Dify项目DSL实战:把财务报销审核助手做成可复用的工程资产

简介:这是一份面向企业财务合规与流程自动化场景的Dify工作流应用资源,支持直接导入项目DSL,聚焦报销单据审核中的规则校验、缺失字段补全、风险等级划分与汇总表输出,适合财务人员、Dify开发者及企业IT运维者直接参考或二次开发。…

2026/10/8 16:01:47

FastAPI实战指南:选型、异步开发、性能优化与部署避坑

1. 为什么我最终选择了FastAPI:一次真实的框架选型复盘先说结论:如果你正在用Python写API,又不想在性能和开发效率之间做取舍,FastAPI是目前我见过平衡做得最好的一个。不管是给内部工具写接口,还是给生产环境搭微服务…

2026/10/8 16:01:47

局域网IP-MAC扫描全攻略:ARP原理、工具选型与Python脚本实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:56:44

嘉立创PCB打板全流程:从嘉立创EDA设计到六层板Gerber下单

这次我们聊一个很多电子爱好者绕不开的话题:嘉立创PCB打板。标题里那句话很有意思——“不靠卖板赚钱,以培养工程师为己任”。先不去评价商业策略,单从结果看,低门槛打样加上嘉立创EDA这套组合,确实让大量学生和个人开…

2026/10/8 10:03:18

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/8 10:03:20

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/8 6:05:44

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 0:02:17

自然数立方等于连续奇数之和:从证明到编程验证

十几年来我一直游走在数学科普和编程教学这两块内容之间,对“看起来像魔法、拆开全是数学”的结论总是格外敏感。最近翻资料时又撞见一句话:任何一个自然数 m 的立方,都可以写成 m 个连续奇数之和。2 的立方等于 3 加 5,3 的立方等…

2026/10/8 0:02:17

C#上位机SSH连接实战:用SSH.NET补齐超时、批量与密钥认证

简介:这是一份基于 C# 开发的 SSH 连接功能半成品工程,原本作为另一个主项目的子功能模块,现独立打包分享。工程采用 WinForms 界面,包含源码、解决方案、安装部署工程、NuGet 依赖包及说明文档,适合正在做远程连接、网…

2026/10/8 0:02:17

Java SpringBoot一体化智能售后系统设计与实现全解析

毕业设计年年做,Java Web 方向的题目翻来覆去就那么几个,但“一体化智能售后系统”这个题,每次看到我都觉得值得认真聊一聊。它不是一个简单 curd 堆出来的管理系统,而是把客户、工单、派单、处理、回访、统计整条链路串起来的一套…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑