位置: 编程技术 - 正文

Nodejs Stream 数据流使用手册(nodejs stdin)

编辑:rootadmin

推荐整理分享Nodejs Stream 数据流使用手册(nodejs stdin),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:nodejs writestream,node.js stream,nodejs stream原理,nodejs stream原理,nodejs stream原理,node.js stream,nodejs stream原理,nodejs readstream,内容如对您有帮助,希望把文章链接给更多的朋友!

1、介绍

本文介绍了使用 node.js streams 开发程序的基本方法。

最早接触Stream是从早期的unix开始的数十年的实践证明Stream 思想可以很简单的开发出一些庞大的系统。在unix里,Stream是通过 |实现的;在node中,作为内置的stream模块,很多核心模块和三方模块都使用到。和unix一样,node Stream主要的操作也是.pipe(),使用者可以使用反压力机制来控制读和写的平衡。

Stream 可以为开发者提供可以重复使用统一的接口,通过抽象的Stream接口来控制Stream之间的读写平衡。

2、为什么使用Stream

node中的I/O是异步的,因此对磁盘和网络的读写需要通过回调函数来读取数据,下面是一个文件下载服务器的简单代码:

这些代码可以实现需要的功能,但是服务在发送文件数据之前需要缓存整个文件数据到内存,如果"data.txt"文件很大且并发量很大的话,会浪费很多内存。因为用户需要等到整个文件缓存到内存才能接受的文件数据,这样导致用户体验相当不好。不过还好(req, res)两个参数都是Stream,这样我们可以用fs.createReadStream()代替fs.readFile():

.pipe()方法监听fs.createReadStream()的'data' 和'end'事件,这样"data.txt"文件就不需要缓存整个文件,当客户端连接完成之后马上可以发送一个数据块到客户端。使用.pipe()另一个好处是可以解决当客户端延迟非常大时导致的读写不平衡问题。如果想压缩文件再发送,可以使用三方模块实现:

这样文件就会对支持gzip和deflate的浏览器进行压缩。oppressor 模块会处理所有的content-encoding。

Stream使开发程序变得简单。

3、基础概念

有五种基本的Stream: readable, writable, transform, duplex, and”classic”.

3-1、pipe

所有类型的Stream收是使用 .pipe() 来创建一个输入输出对,接收一个可读流src并将其数据输出到可写流dst,如下:

.pipe( dst )方法为返回dst流,这样就可以接连使用多个.pipe(),如下:

功能与下面的代码相同:

3-2、readable streams

通过调用Readable streams的 .pipe()方法可以把Readable streams的数据写入一个Writable , Transform, 或者Duplex stream。

1>创建 readable stream

这里我们创建一个readable stream!

rs.push( null ) 通知数据接收者数据已经发送完毕.

注意到我们在将所有数据内容压入可读流之前并没有调用rs.pipe(process.stdout);,但是我们压入的所有数据内容还是完全的输出了,这是因为可读流在接收者没有读取数据之前,会缓存所有压入的数据。但是在很多情况下, 更好的方法是只有数据接收着请求数据的时候,才压入数据到可读流而不是缓存整个数据。下面我们重写 一下._read()函数:

上面的代码通过重写_read()方法实现了只有在数据接受者请求数据才向可读流中压入数据。_read()方法也可以接收一个size参数表示数据请求着请求的数据大小,但是可读流可以根据需要忽略这个参数。

注意我们也可以用util.inherits()继承可读流。为了说明只有在数据接受者请求数据时_read()方法才被调用,我们在向可读流压入数据时做一个延时,如下:

用下面的命令运行程序我们发现_read()方法只调用了5次:

使用计时器的原因是系统需要时间来发送信号来通知程序关闭管道。使用process.stdout.on('error', fn) 是为了处理系统因为header命令关闭管道而发送SIGPIPE信号,因为这样会导致process.stdout触发EPIPE事件。如果想创建一个的可以压入任意形式数据的可读流,只要在创建流的时候设置参数objectMode为true即可,例如:Readable({ objectMode: true })。

2>读取readable stream数据

大部分情况下我们只要简单的使用pipe方法将可读流的数据重定向到另外形式的流,但是在某些情况下也许直接从可读流中读取数据更有用。如下:

Nodejs Stream 数据流使用手册(nodejs stdin)

当可读流中有数据可读取时,流会触发'readable' 事件,这样就可以调用.read()方法来读取相关数据,当可读流中没有数据可读取时,.read() 会返回null,这样就可以结束.read() 的调用, 等待下一次'readable' 事件的触发。下面是一个使用.read(n)从标准输入每次读取3个字节的例子:

如下运行程序发现,输出结果并不完全!

这是应为额外的数据数据留在流的内部缓冲区里了,而我们需要通知流我们要读取更多的数据.read(0)可以达到这个目的。

这次运行结果如下:

我们可以使用 .unshift() 将数据重新押回流数据队列的头部,这样可以接续读取押回的数据。如下面的代码,会按行输出标准输入的内容:

当然,有很多模块可以实现这个功能,如:split 。

3-3、writable streams

writable streams只可以作为.pipe()函数的目的参数。如下代码:

1>创建 writable stream

重写 ._write(chunk, enc, next) 方法就可以接受一个readable stream的数据。

第一个参数chunk是数据输入者写入的数据。第二个参数end是数据的编码格式。第三个参数next(err)通过回调函数通知数据写入者可以写入更多的时间。如果readable stream写入的是字符串,那么字符串会默认转换为Buffer,如果在创建流的时候设置Writable({ decodeStrings: false })参数,那么不会做转换。如果readable stream写入的数据时对象,那么需要这样创建writable stream

2>写数据到 writable stream

调用writable stream的.write(data)方法即可完成数据写入。

调用.end()方法通知writable stream 数据已经写入完成。

如果需要设置writable stream的缓冲区的大小,那么在创建流的时候,需要设置opts.highWaterMark,这样如果缓冲区里的数据超过opts.highWaterMark,.write(data)方法会返回false。当缓冲区可写的时候,writable stream会触发'drain' 事件。

3-4、classic streams

Classic streams比较老的接口了,最早出现在node 0.4版本中,但是了解一下其运行原理还是十分有好处的。当一个流被注册了"data" 事件的回到函数,那么流就会工作在老版本模式下,即会使用老的API。

1>classic readable streams

Classic readable streams事件就是一个事件触发器,如果Classic readable streams有数据可读取,那么其触发 "data" 事件,等到数据读取完毕时,会触发"end" 事件。.pipe() 方法通过检查stream.readable 的值确定流是否有数据可读。下面是一个使用Classic readable streams打印A-J字母的例子:

如果要从classic readable stream中读取数据,注册"data" 和"end"两个事件的回调函数即可,代码如下:

需要注意的是如果你使用这种方式读取数据,那么会失去使用新接口带来的好处。比如你在往一个 延迟非常大的流写数据时,需要注意读取数据和写数据的平衡问题,否则会导致大量数据缓存在内存中,导致浪费大量内存。一般这时候强烈建议使用流的.pipe()方法,这样就不用自己监听”data” 和”end”事件了,也不用担心读写不平衡的问题了。当然你也可以用 through代替自己监听”data” 和”end” 事件,如下面的代码:

或者也可以使用concat-stream来缓存整个流的内容:

当然如果你非要自己监听"data" 和"end"事件,那么你可以在写数据的流不可写的时候使用.pause()方法暂停Classic readable streams继续触发”data” 事件。等到写数据的流可写的时候再使用.resume() 方法通知流继续触发"data" 事件继续读取数据。

2>classic writable streams

Classic writable streams 非常简单。只有 .write(buf), .end(buf)和.destroy()三个方法。.end(buf) 方法的buf参数是可选的,如果选择该参数,相当于stream.write(buf); stream.end() 这样的操作,需要注意的是当流的缓冲区写满即流不可写时.write(buf)方法会返回false,如果流再次可写时,流会触发drain事件。

4、transform

transform是一个对读入数据过滤然输出的流。

5、duplex

duplex stream是一个可读也可写的双向流,如下面的a就是一个duplex stream:

以上内容是小编给大家介绍的Nodejs Stream 数据流使用手册,希望对大家有所帮助!

基于 Node.js 实现前后端分离 基本介绍首先从一个重要的概念模板说起。广义上来说,web中的模板就是填充数据后可以生成文件的页面。严格意义上来说,应该是模板引擎利用特定

基于node实现websocket协议 一、协议WebSocket是一种基于TCP之上的客户端与服务器全双工通讯的协议,它在HTML5中被定义,也是新一代webapp的基础规范之一。它突破了早先的AJAX的限

Windows 系统下设置Nodejs NPM全局路径 在开发过程中我们可能希望重新设置npm的全局路径,具体方法如下:npmconfigsetcache"D:nodejsnode_cache"npmconfigsetprefix"D:nodejsnode_global"

标签: nodejs stdin

本文链接地址:https://www.jiuchutong.com/biancheng/370722.html 转载请保留说明!

上一篇:node.js连接mongoDB数据库 快速搭建自己的web服务(node.js连接mysql的数据怎么可视化)

下一篇:基于 Node.js 实现前后端分离(node-js)

  • 计提的增值税和实际缴纳的差额
  • 个人独资企业和个体工商户的税收区别
  • 中税协是什么意思
  • 集体房屋出租管理办法
  • 出口退税分类管理办法最新
  • 所得税费用是什么科目
  • 定金冲抵货款怎么做分录
  • 税控盘维护费开的是普票可以抵扣吗
  • 买手机手续费怎么算
  • 成品油红字发票开错了
  • 出售无形资产的净损失
  • 向境外分配股息
  • 房产契税发票丢了可以补开吗
  • 合伙企业个人所得税怎么申报
  • 企业收到赞助费
  • 在建工程转什么
  • 工程结算与工程施工如何结转
  • 网银费用及回单箱费用账务处理?
  • 企业停产或停业期间的费用包括
  • 公司给员工的商业保险
  • 贸易公司出口退税流程及账务处理
  • 技术开发费税收优惠政策
  • 福利费进项税额转出会计分录账务处理
  • 单边征收
  • 专用发票百万元版申请要求
  • 票据贴现手续费发票可以抵扣吗
  • 进口车关税怎么抵扣
  • 会员卡充值赠送金额怎么做账
  • 帐外资产 如何记账
  • 经营方式变更说明
  • 餐饮业管理费用明细表
  • 进项认证转出 会计得入账吗
  • 未到期的商业票据是什么
  • 合伙企业财产的管理和使用规定
  • 分摊本月领用材料的成本差异
  • Win10 21H2 Build 21354 ISO 太阳谷官方镜像预览版下载
  • linux中qq怎么添加快捷键启动功能?
  • 软件开发公司排行榜
  • php字符串定义的三种方式
  • 担保公司计提的费用
  • 公司的房租收入要交税吗
  • 对账小技巧
  • 企业销售货物收到价款5000元这笔经济业务属于
  • 前端实现微信联系人二维码
  • ajax如何返回数据
  • 饭店的手撕发票可以报销吗
  • vm网络不可达
  • GCC strict aliasing – 嫉妒就是承认自己不如别人
  • 私房出租税收
  • 长期股权投资种类
  • 报废的机器设备属于什么会计要素
  • 销售旧货的增值税是销项税吗
  • 现金流量表现金净增加额负数
  • 民间非营利组织财务管理制度
  • 购买其他权益工具投资公允大于我支付的价值
  • 银行结息交易是扣钱的意思吗
  • 资产减值准备怎么提
  • 税控盘减免税款月末不用交税还要结转吗
  • 油卡办理需要多久?
  • 租来设备本身原因致人损害
  • 福利费要交个人所得税嘛
  • 结算本月应付职工工资,其中生产工人工资8000元
  • windows 配置
  • mysql_error
  • centos svn服务器搭建web
  • 安装win7系统需要注意什么
  • 为什么多出一个系统
  • win7盘符不见了
  • 详解linux中systemd命令的运行级别与其常见应用
  • 如何用法向量求点到线的距离
  • cocos2dx开发的游戏有哪些
  • jq拖拽div替换位置
  • delect删除
  • unity热更新框架对比
  • js初级教程
  • android中常用的adapter不包括
  • 纳税申报表如何看销售额
  • 保险公司个人所得税扣除标准是多少
  • 物流公司怎么申请TIR
  • 江苏省人大有信访工作吗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设