Node 中的 Stream ?应用场景?

一、是什么
流(Stream),是一种数据传输手段,是端到端信息交换的一种方式,是有顺序的,是逐块读取数据、处理内容,用于顺序读取输入或写入输出
在很多时候,流(Stream)是字节流(Byte Steram)的简称,也就是长长的一串字节
除了字节流,还可以有视频流、音频流、数据流
流的独特之处在于,它不像传统的程序那样一次将一个文件读入内存,而是逐块读取数据、处理其内容,而不是将其全部保存在内存中
流可以分成三部分:source、dest、pipe
在source和dest之间有一个连接的管道pipe,它的基本语法是source.pipe(dest),source和dest就是通过pipe连接,让数据从source流向了dest,如下图所示:
二、种类
在NodeJS,几乎所有的地方都使用到了流的概念,分成四个种类:
可写流:可写入数据的流。例如 fs.createWriteStream() 可以使用流将数据写入文件
可读流:可读取数据的流。例如fs.createReadStream() 可以从文件读取内容
双工流:既可读又可写的流。例如 net.Socket
转换流:可以在数据写入和读取时修改或转换数据的流。例如,在文件压缩操作中,可以向文件写入压缩数据,并从文件中读取解压数据
在NodeJS中HTTP服务器模块中,request 是可读流,response 是可写流。还有fs 模块,能同时处理可读和可写文件流
可读流和可写流都是单向的,比较容易理解,而另外两个是双向的
双工流
之前了解过websocket通信,是一个全双工通信,发送方和接受方都是各自独立的方法,发送和接收都没有任何关系
如下图所示:
基本代码如下:
const { Duplex } = require('stream');
const myDuplex = new Duplex({
read(size) {
// ...
},
write(chunk, encoding, callback) {
// ...
}
});
转换流
转换流的演示图如下所示:
比如一个 babel,把es6转换为es5,我们在左边写入 es6,从右边读取 es5
基本代码如下所示:
const { Transform } = require('stream');
const myTransform = new Transform({
transform(chunk, encoding, callback) {
// ...
}
});
三、应用场景
stream的应用场景主要就是处理IO操作,而http请求和文件操作都属于IO操作
思想一下,如果一次IO操作过大,硬件的开销就过大,而将此次大的IO操作进行分段操作,让数据像水管一样流动,知道流动完成
常见的场景有:
- get请求返回文件给客户端
- 文件操作
- 一些打包工具的底层操作
get请求返回文件给客户端
使用stream流返回文件,res也是一个stream对象,通过pipe管道将文件数据返回
const server = http.createServer(function (req, res) {
const method = req.method; // 获取请求方法
if (method === 'GET') { // get 请求
const fileName = path.resolve(__dirname, 'data.txt');
let stream = fs.createReadStream(fileName);
stream.pipe(res); // 将 res 作为 stream 的 dest
}
});
server.listen(8000);
文件操作
创建一个可读数据流readStream,一个可写数据流writeStream,通过pipe管道把数据流转过去
const fs = require('fs')
const path = require('path')
// 两个文件名
const fileName1 = path.resolve(__dirname, 'data.txt')
const fileName2 = path.resolve(__dirname, 'data-bak.txt')
// 读取文件的 stream 对象
const readStream = fs.createReadStream(fileName1)
// 写入文件的 stream 对象
const writeStream = fs.createWriteStream(fileName2)
// 通过 pipe执行拷贝,数据流转
readStream.pipe(writeStream)
// 数据读取完成监听,即拷贝完成
readStream.on('end', function () {
console.log('拷贝完成')
})
一些打包工具的底层操作
目前一些比较火的前端打包构建工具,都是通过node.js编写的,打包和构建的过程肯定是文件频繁操作的过程,离不开stream,如gulp
参考文献
- https://xie.infoq.cn/article/1a9695020828460eb3c4ff1fa
- https://juejin.cn/post/6844903891083984910
Node 中的 Stream ?应用场景?的更多相关文章
- node中的Stream-Readable和Writeable解读
在node中,只要涉及到文件IO的场景一般都会涉及到一个类-Stream.Stream是对IO设备的抽象表示,其在JAVA中也有涉及,主要体现在四个类-InputStream.Reader.Outpu ...
- Node 中的 stream (流)
流的概念 流(stream)在 Node.js 中是处理流数据的抽象接口(abstract interface). stream 模块提供了基础的 API .使用这些 API 可以很容易地来构建实现流 ...
- node中的stream(流)内置模块
stream是Node.js提供的又一个仅在服务区端可用的模块,目的是支持“流”这种数据结构. 什么是流?流是一种抽象的数据结构.想象水流,当在水管中流动时,就可以从某个地方(例如自来水厂)源源不断地 ...
- node中的Readable - flowing/non-flowing mode
大家都知道在node中Readable Stream有两种模式: flowing mode和non-flowing mode. 对于flowing mode的Readable Stream, 我们是没 ...
- 深入理解jQuery、Angular、node中的Promise
最初遇到Promise是在jQuery中,在jQuery1.5版本中引入了Deferred Object,这个异步队列模块用于实现异步任务和回调函数的解耦.为ajax模块.队列模块.ready事件提供 ...
- Node.js 【Stream之笔记】
从Node.js API文档中可知, 'A stream is an abstract interface implemented by various objects in Node. For ex ...
- jdk8中的stream
https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/ Java 8 中的 Streams API 详解 Streams 的背景 ...
- node中异步IO的理解
解释性语言和编译型语言的区别: 计算器不能直接的理解高级语言,只能理解机器语言,所以必须把高级语言翻译为机器语言,翻译的方式有两种,一个是编译,一个是解释. 解释性语言的程序不需要编译,它是在运行程序 ...
- Node.js:Stream(流)
Stream 是一个抽象接口,Node 中有很多对象实现了这个接口.例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出). Node.js,Str ...
- 【Node.js】Stream(流)的学习笔记
最近学习使用Node.js创建http proxy server,少不了要跟Stream打交道.昨天开始查阅一些资料,多少有了一些粗浅了解.整理在这里,供学习之用. 从Node.js API文档中可知 ...
随机推荐
- 【拉格朗日优化dp】P4365 [九省联考 2018] 秘密袭击 coat
[拉格朗日优化dp]P4365 [九省联考 2018] 秘密袭击 coat 题目简述 求树上所有连通块第 \(k\) 大点权(不足 \(k\) 点记为 \(0\))的和. \(1\leq k\leq ...
- matlab修改读取mat文件后的变量名
代码如下: %% str1=load('CH1.mat'); val_names = fieldnames(str1); % 获取结构体后那个未知的变量名 data1 = getfield(str1, ...
- Spring配置xml自定义事务管理器
上一篇博客讲解了Spring配置xml事务,使用的是Spring框架提供的事务管理器. 在本篇博文当中,来讲解一下使用自定义的事务管理方式. 把上一篇博文当中的这个配置 <bean id=&qu ...
- 2.String类能被继承吗
2.String类能被继承吗 不可以,因为String类有final修饰符,而final修饰的类是不能被继承的. 拓展 String的底层是一个用private和final修饰的char数组.fina ...
- manjaro系统的xfce桌面环境的的壁纸存放位置
/usr/share/backgrounds/xfce 添加新照片的命令是: sudo mv 目录/* /usr/share/backgrounds/xfce
- js实现回调功能实例
所谓js回调,本人认为无非就是一个函数的参数是另外一个函数,而作为参数的函数就称之为回调函数 <script type="text/javascript"> //要请 ...
- 初识uds之abstract socket
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 环境说明 无 前言 在<记一次有趣的hwclock ...
- 崩溃bug日志总结1
目录介绍 1.1 java.lang.UnsatisfiedLinkError找不到so库异常 1.2 java.lang.IllegalStateException非法状态异常 1.3 androi ...
- Linux服务器部署Web版VSCode,在window下使用浏览器在linux环境下编写代码
最近尝试了一下在Linux服务器上部署VSCode,也就是code-server,然后在windows电脑上通过浏览器访问打开在线编辑器编写代码,以下记录一下部署过程. 1.在linux服务器上安装c ...
- PS的流水灯设计分析
PS的流水灯设计分析 1.实验原理 PS设计流水灯就是采用ARM的硬核实现流水灯设计.ARM内核采用的就是一个可以执行软件程序的平台.这里采用C语言设计.基于前面构建的GPIO外设的硬件平台,这里实现 ...