0

0

浅析Node.js 中 Stream API 的使用

高洛峰

高洛峰

发布时间:2016-12-28 13:18:22

|

1761人浏览过

|

来源于php中文网

原创

本文由浅入深给大家介绍node.js stream api,具体详情请看下文吧。

基本介绍

在 Node.js 中,读取文件的方式有两种,一种是用 fs.readFile ,另外一种是利用 fs.createReadStream 来读取。

fs.readFile 对于每个 Node.js 使用者来说最熟悉不过了,简单易懂,很好上手。但它的缺点是会先将数据全部读入内存,一旦遇到大文件的时候,这种方式读取的效率就非常低下了。

而 fs.createReadStream 则是通过 Stream 来读取数据,它会把文件(数据)分割成小块,然后触发一些特定的事件,我们可以监听这些事件,编写特定的处理函数。这种方式相对上面来说,并不好上手,但它效率非常高。

事实上, Stream 在 Node.js 中并非仅仅用在文件处理上,其他地方也可以看到它的身影,如 process.stdin/stdout , http , tcp sockets , zlib , crypto 等都有用到。

本文是我学习 Node.js 中的 Stream API 中的一点总结,希望对大家有用。

特点

基于事件通讯

可以通过 pipe 来连接流

种类

Readable Stream 可读数据流

Writeable Stream 可写数据流

Duplex Stream 双向数据流,可以同时读和写

Transform Stream 转换数据流,可读可写,同时可以转换(处理)数据

事件

可读数据流的事件

readable 数据向外流时触发

data 对于那些没有显式暂停的数据流,添加data事件监听函数,会将数据流切换到流动态,尽快向外提供数据

end 读取完数据时触发。注意不能和 writeableStream.end() 混淆,writeableStream 并没有 end 事件,只有 .end() 方法

close 数据源关闭时触发

error 读取数据发生错误时触发

可写数据流的事件

drain writable.write(chunk) 返回 false 之后,缓存全部写入完成,可以重新写入时就会触发

finish 调用 .end 方法时,所有缓存的数据释放后触发,类似于可读数据流中的 end 事件,表示写入过程结束

pipe 作为 pipe 目标时触发

unpipe 作为 unpipe 目标时触发

error 写入数据发生错误时触发

浅析HTML5在移动应用开发中的使用
浅析HTML5在移动应用开发中的使用

浅析HTML5在移动应用开发中的使用

下载

状态

可读数据流有两种状态: 流动态 和 暂停态 ,改变数据流状态的方法如下:

暂停态 -> 流动态

添加 data 事件的监听函数

调用 resume 方法

调用 pipe 方法

注意:如果转为流动态时,没有 data 事件的监听函数,也没有 pipe 方法的目的地,那么数据将遗失。

流动态 -> 暂停态

不存在 pipe 方法的目的地时,调用 pause 方法

存在 pipe 方法的目的地时,移除所有 data 事件的监听函数,并且调用 unpipe 方法,移除所有 pipe 方法的目的地

注意:只移除 data 事件的监听函数,并不会自动引发数据流进入「暂停态」。另外,存在 pipe 方法的目的地时,调用 pause 方法,并不能保证数据流总是处于暂停态,一旦那些目的地发出数据请求,数据流有可能会继续提供数据。

用法

读写文件

var fs = require('fs');
// 新建可读数据流
var rs = fs.createReadStream('./test1.txt');
// 新建可写数据流
var ws = fs.createWriteStream('./test2.txt');
// 监听可读数据流结束事件
rs.on('end', function() {
 console.log('read text1.txt successfully!');
});
// 监听可写数据流结束事件
ws.on('finish', function() {
 console.log('write text2.txt successfully!');
});
// 把可读数据流转换成流动态,流进可写数据流中
rs.pipe(ws);
读取 CSV 文件,并上传数据(我在生产环境中写过)
var fs = require('fs');
var es = require('event-stream');
var csv = require('csv');
var parser = csv.parse();
var transformer = csv.transform(function(record) {
 return record.join(',');
});
var data = fs.createReadStream('./demo.csv');
data
 .pipe(parser)
 .pipe(transformer)
 // 处理前一个 stream 传递过来的数据
 .pipe(es.map(function(data, callback) {
  upload(data, function(err) {
   callback(err);
  });
 }))
 // 相当于监听前一个 stream 的 end 事件
 .pipe(es.wait(function(err, body) {
  process.stdout.write('done!');
 }));

更多用法

可以参考一下 https://github.com/jeresig/node-stream-playground ,进去示例网站之后直接点 add stream 就能看到结果了。

常见坑

用 rs.pipe(ws) 的方式来写文件并不是把 rs 的内容 append 到 ws 后面,而是直接用 rs 的内容覆盖 ws 原有的内容

已结束/关闭的流不能重复使用,必须重新创建数据流

pipe 方法返回的是目标数据流,如 a.pipe(b) 返回的是 b,因此监听事件的时候请注意你监听的对象是否正确

如果你要监听多个数据流,同时你又使用了 pipe 方法来串联数据流的话,你就要写成:

data

.on('end', function() {
 console.log('data end');
})
.pipe(a)
.on('end', function() {
 console.log('a end');
})
.pipe(b)
.on('end', function() {
 console.log('b end');
});

常用类库

event-stream 用起来有函数式编程的感觉,个人比较喜欢

awesome-nodejs#streams 由于其他 stream 库我都没用过,所以有需求的就直接看这里吧

以上内容是小编给大家介绍的Node.js 中 Stream API 的使用,希望大家喜欢。

更多浅析Node.js 中 Stream API 的使用相关文章请关注PHP中文网!

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
AO3官网入口与中文阅读设置 AO3网页版使用与访问
AO3官网入口与中文阅读设置 AO3网页版使用与访问

本专题围绕 Archive of Our Own(AO3)官网入口展开,系统整理 AO3 最新可用官网地址、网页版访问方式、正确打开链接的方法,并详细讲解 AO3 中文界面设置、阅读语言切换及基础使用流程,帮助用户稳定访问 AO3 官网,高效完成中文阅读与作品浏览。

3

2026.02.02

主流快递单号查询入口 实时物流进度一站式追踪专题
主流快递单号查询入口 实时物流进度一站式追踪专题

本专题聚合极兔快递、京东快递、中通快递、圆通快递、韵达快递等主流物流平台的单号查询与运单追踪内容,重点解决单号查询、手机号查物流、官网入口直达、包裹进度实时追踪等高频问题,帮助用户快速获取最新物流状态,提升查件效率与使用体验。

0

2026.02.02

Golang WebAssembly(WASM)开发入门
Golang WebAssembly(WASM)开发入门

本专题系统讲解 Golang 在 WebAssembly(WASM)开发中的实践方法,涵盖 WASM 基础原理、Go 编译到 WASM 的流程、与 JavaScript 的交互方式、性能与体积优化,以及典型应用场景(如前端计算、跨平台模块)。帮助开发者掌握 Go 在新一代 Web 技术栈中的应用能力。

1

2026.02.02

PHP Swoole 高性能服务开发
PHP Swoole 高性能服务开发

本专题聚焦 PHP Swoole 扩展在高性能服务端开发中的应用,系统讲解协程模型、异步IO、TCP/HTTP/WebSocket服务器、进程与任务管理、常驻内存架构设计。通过实战案例,帮助开发者掌握 使用 PHP 构建高并发、低延迟服务端应用的工程化能力。

1

2026.02.02

Java JNI 与本地代码交互实战
Java JNI 与本地代码交互实战

本专题系统讲解 Java 通过 JNI 调用 C/C++ 本地代码的核心机制,涵盖 JNI 基本原理、数据类型映射、内存管理、异常处理、性能优化策略以及典型应用场景(如高性能计算、底层库封装)。通过实战示例,帮助开发者掌握 Java 与本地代码混合开发的完整流程。

1

2026.02.02

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

61

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

52

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

25

2026.01.31

golang 循环遍历
golang 循环遍历

本专题整合了golang循环遍历相关教程,阅读专题下面的文章了解更多详细内容。

10

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
nodejs开发基础教程
nodejs开发基础教程

共15课时 | 4.5万人学习

Express 中文开发手册
Express 中文开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号