【Node.js】Stream(流)的学习笔记
最近学习使用Node.js创建http proxy server,少不了要跟Stream打交道。昨天开始查阅一些资料,多少有了一些粗浅了解。整理在这里,供学习之用。
从Node.js API文档中可知,
"A stream is an abstract interface implemented by various objects in Node. For example a request to an HTTP server is a stream, as is stdout. Streams are readable, writable, or both. All streams are instances of EventEmitter。""流是很多I/0操作的抽象,被 Node 中的很多对象所实现。比如对一个 HTTP 服务器的请求是一个流(可读流)(服务器的响应是一个流(可写流)),stdout也是流。流是可读、可写或兼具两者的。所有流都是 EventEmitter 的实例。"
一. 为什么需要流(Stream)?
举个例子,如果要读取一个文件,一次性读取需要占用大内存,是不可取的。因此就有了流,用流会很方便,可以帮我们避免这样的问题,调用其接口不用关心底层如何实现。
二. 什么是流(Stream)?
流(Stream)是可读,可写或双工的。可以通过require('stream')加载流的基类,其中包括四类流, Readable 流、Writable 流、Duplex 流和Transform 流的基类。
另外如果觉得上述四类基类流不能满足需求,可以编写自己的扩充类流。像我们Team现在正做的Node项目,就重写了Transform类以供使用。
按照官方的API文档,步骤如下:
- 在您的子类中扩充适合的父类。(例如util.inherits(MyTransform, Transform); )
- 在您的构造函数中调用父类的构造函数,以确保内部的机制被正确初始化。
- 实现一个或多个特定的方法,参见下面的细节。
三. Readable流(可读流)介绍
Readable(可读)流接口是对您正在读取的数据的来源的抽象。换言之,数据出自一个可读流。
Readable 流有两种“模式”:流动模式和暂停模式。
当处于流动模式时,数据由底层系统读出,并尽可能快地提供给您的程序;当处于暂停模式时,您必须明确地调用 stream.read()
来取出若干数据块。流默认处于暂停模式。
A. 通过以下三种方法,可读流会被切换到流动模式
1. 添加一个'data'事件处理器来监听数据。
2. 调用 resume()方法来明确开启数据流。
3. 调用 pipe()方法将数据发送到一个可写流(Writable)。
之前我一直对pipe()方法有疑问,不清楚其用法。现在了解,当我们用pipe()为可读流指定了一个接受者(可写流)的时候,数据才会真正的被从底层系统读出,传递给可写流。
B. 下面介绍Readable流有以下几种事件
1. 'Readable'事件
2. 'data'事件 - 数据正在传递时,触发该事件(以chunk数据块为对象)
3. 'end'事件 - 数据传递完成后,会触发该事件。
4. 'close'事件
5. 'error'事件
所有这些事件都可以在官方API文档中找到例子。
C. 下面介绍Readable流很重要的一个方法,pipe()方法。
该方法从可读流中拉取所有数据,并写入到所提供的目标(可写流)。该方法能自动控制流量以避免目标被快速读取的可读流所淹没。
值得注意的是,默认情况下,当数据传送完毕,触发'end'事件时,会同时触发目标(可写流)的'end'事件,导致目标不再可写。
举个简单的小例子,
//http.js var http = require('http');
var fs = require('fs'); http.createServer(function(req, res){
var stream = fs.createReadStream(__dirname + '/data.txt');
stream.pipe(res);
}).listen(3000); console.log('now we are listening 3000 port');
data.txt文件内容如下:
当执行此段代码后,用户访问http://127.0.0.1:3000/,会得到如下响应:
此时,创建此Server后,用户访问请求过来,Server会创建一个可读流,当调用stream.pipe(res)为可读流指定目标后,可读流stream会开始从文件data.txt中读取数据,数据写入res(可写流)完毕后,自动调用res的end()方法,结束响应,可写流不再写入。
四. Writable流(可写流)介绍
Writable(可写)流接口是对写入数据的目标的抽象。
可写流重要的两个方法,
1. write()方法
该方法向底层系统写入数据,并在数据被处理完毕后调用所给的回调。
2. end()方法
当不再写入数据时,调用该方法,停止写入。在调用end()后,再调用write()方法会产生错误。
五. 参考资料
1. Node.js官方API文档
http://www.nodejs.org/api/stream.html
2. 官方API文档中文版
http://nodeapi.ucdok.com/#/api/stream.html
3. Node 中的流(Stream)
http://blog.segmentfault.com/xingrz/1190000000357044
4. Node Streams: How do they work?
http://maxogden.com/node-streams.html
抛砖引玉,继续加油。
Best Regards
Kevin Song
- 2014/6/18
【Node.js】Stream(流)的学习笔记的更多相关文章
- 9、Node.js Stream(流)
#########################################################################介绍Node.js Stream(流)Stream 是 ...
- Node.js stream 流学习
由于node.js 创建http 是这样的 http.createServer(function(request,response){}).listen(2000); 里面的request 就是rea ...
- 《Node.js核心技术教程》学习笔记
<Node.js核心技术教程>TOC \o "1-3" \h \z \u 1.章模块化编程 2019.2.19 13:30' PAGEREF _101 \h 1 08D ...
- Node.js Stream(流)
Stream 是一个抽象接口,Node 中有很多对象实现了这个接口.例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出). Node.js,Str ...
- 24.Node.js Stream(流)
转自:http://www.runoob.com/nodejs/nodejs-stream.html Stream 是一个抽象接口,Node 中有很多对象实现了这个接口.例如,对http 服务器发起请 ...
- Node.js amqplib 连接 Rabbitmq 学习笔记
var amqp = require('amqplib'); connect([url, [socketOptions]]) var amqp = require('amqplib/callback_ ...
- 《JS高程》事件学习笔记
事件:文档或浏览器窗口中发生的一些特定的交互瞬间,也即用户或浏览器自身执行的某种动作. -------------------------------------------------------- ...
- 【特别推荐】Node.js 入门教程和学习资源汇总
这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
- Node.js 入门教程和学习资源汇总
这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
- Node.js环境搭建和学习(windwos环境)
Node.js环境搭建和学习 一.环境搭建 1.下载安装文件 下载地址http://nodejs-org.qiniudn.com/下载Node.js环境安装包,根据操作系统下载对应的安装包 下载地址 ...
随机推荐
- CF959D Mahmoud and Ehab and another array construction task 数学
Mahmoud has an array a consisting of n integers. He asked Ehab to find another array b of the same l ...
- django组件之ajax
AJAX简介 AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异步交互,传输的数 ...
- Jenkins自动化CI CD流水线之5--pipeline
一.概览 二.安装 在对jenkins进行初始化安装时,默认已经安装了jenkins的相关插件,如下图所示: 三.实操 新建任务: 编写pipeline脚本: 我们可以借助流水线语法去做. test流 ...
- 小程序自定义modal弹窗封装实现
前言小程序官方提供了 wx.showModal 方法,但样式比较固定,不能满足多元化需求,自定义势在必行~ 老规矩先上图 点击某个按钮,弹出 modal框,里面的内容可以自定义,可以是简单的文字提示, ...
- 原 tomcat的server.xml配置文件中三个端口的作用
以Tomcat7.0为例, 在安装目录下. conf/server.xml 中可以配置三个端口号, 如果使用多个tomcat 是需要配置这三个. 该Connector 用于监听请求. protocol ...
- 读书笔记 - 《黑旗 ISIS的崛起》
不愧是普利策奖的书籍,读起来让人欲罢不能,花了大约四个晚上把此书一气读完.这本书讲述的是“伊斯兰国”ISIS及其前身组织历史,也就是阿布·穆萨卡·扎卡维及其追随者的故事.虽然不是小说,但故事的精彩以及 ...
- vi或vim下按方向键改变方向变成ABCD这类字符
遇到这种问题肯定很恼火,按方向键改变文本的方向有时候变成输入ABCD,有时候并不是我们想要的结果 解决方法: $ echo "set nocp" >> ~/.vimrc ...
- vue-cli构建的vue项目打包后css引入的背景图路径不对的问题
使用vue-cli构建vue项目后,再打包遇到一个css引入的背景图片路径的问题,就是css代码中背景图片是根据相对路径来写的,如下图: 当使用npm run dev命令本地访问的时候,背景图片是正常 ...
- 转载 Some indexes or index [sub]partitions of table VAS.TAB_PUB_CALLLOG have been marked unusable
http://www.xifenfei.com/2011/12/some-indexes-or-index-subpartitions-of-table-vas-tab_pub_calllog-hav ...
- [编程题] 小易喜欢的数列 dp
https://www.nowcoder.com/question/next?pid=6291726&qid=112729&tid=12736753 [编程题] 小易喜欢的数列 时间限 ...