news 2026/8/13 7:17:43

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Node.js入门教程(十八):Stream(流)

一、什么是 Stream?

Node.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(转换)
常用事件dataenderrorfinish
管道流pipe()方法将可读流连接到可写流
链式流多个pipe()串联,形成处理链
压缩/解压使用zlib模块配合转换流实现
控制流pause()resume()destroy()控制流的行为

提示:Stream 是 Node.js 高效处理 I/O 的核心机制。对于大文件处理、网络数据传输等场景,使用 Stream 可以显著降低内存占用,提升应用性能。管道流(pipe)是 Stream 中最常用的操作模式,可以简洁地将数据从源头传递到目的地。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/13 7:12:50

基于Rust与本地模型的AI Agent桌面应用开发实践

1. 项目缘起:一个“不务正业”的周末与Agent的落地冲动最近两年,AI Agent这个概念在圈子里火得不行,各种框架、论文、Demo层出不穷,感觉不聊两句Agent都不好意思说自己在搞AI。但说实话,看多了那些“xx分钟构建Agent”…

作者头像 李华
网站建设 2026/8/13 7:11:53

大模型核心概念解析:Token、上下文窗口与成本优化实战指南

1. 从“字”到“词片”:理解大模型的“货币”Token当我们谈论大模型时,无论是ChatGPT、文心一言还是通义千问,一个绕不开的核心概念就是“Token”。你可以把它理解为大模型世界里的“基本货币”或“最小计价单位”。但它的定义和我们日常理解…

作者头像 李华
网站建设 2026/8/13 7:10:12

Kimi K3 AI PPT生成工具评测:从自然语言到演示文稿的实践指南

这次我们来看一个在AI演示文稿生成领域引发关注的项目:Kimi K3。它并非一个开源模型或本地部署工具,而是月之暗面(Moonshot AI)旗下Kimi智能助手在演示文稿(PPT)生成能力上的一次重大升级。根据网络上的公开…

作者头像 李华
网站建设 2026/8/13 7:09:00

CentOS Stream 9 从安装到运维:企业级Linux服务器部署实战指南

1. 从零到一:为什么选择CentOS Stream 9作为你的新起点最近在社区里看到不少朋友在问CentOS 9的安装配置,结合最近一些网络热词,比如“centos9镜像下载”、“linux国产”这些,感觉大家对于新一代的企业级Linux发行版既好奇又有点无…

作者头像 李华