一、是什么

流(Stream),是一种数据传输手段,是端到端信息交换的一种方式,是有顺序的,是逐块读取数据、处理内容,用于顺序读取输入或写入输出

在很多时候,流(Stream)是字节流(Byte Steram)的简称,也就是长长的一串字节

除了字节流,还可以有视频流、音频流、数据流

流的独特之处在于,它不像传统的程序那样一次将一个文件读入内存,而是逐块读取数据、处理其内容,而不是将其全部保存在内存中

流可以分成三部分:sourcedestpipe

sourcedest之间有一个连接的管道pipe,它的基本语法是source.pipe(dest)sourcedest就是通过pipe连接,让数据从source流向了dest,如下图所示:

二、种类

NodeJS,几乎所有的地方都使用到了流的概念,分成四个种类:

  • 可写流:可写入数据的流。例如 fs.createWriteStream()  可以使用流将数据写入文件

  • 可读流:可读取数据的流。例如fs.createReadStream() 可以从文件读取内容

  • 双工流:既可读又可写的流。例如 net.Socket

  • 转换流:可以在数据写入和读取时修改或转换数据的流。例如,在文件压缩操作中,可以向文件写入压缩数据,并从文件中读取解压数据

NodeJSHTTP服务器模块中,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 ?应用场景?的更多相关文章

  1. node中的Stream-Readable和Writeable解读

    在node中,只要涉及到文件IO的场景一般都会涉及到一个类-Stream.Stream是对IO设备的抽象表示,其在JAVA中也有涉及,主要体现在四个类-InputStream.Reader.Outpu ...

  2. Node 中的 stream (流)

    流的概念 流(stream)在 Node.js 中是处理流数据的抽象接口(abstract interface). stream 模块提供了基础的 API .使用这些 API 可以很容易地来构建实现流 ...

  3. node中的stream(流)内置模块

    stream是Node.js提供的又一个仅在服务区端可用的模块,目的是支持“流”这种数据结构. 什么是流?流是一种抽象的数据结构.想象水流,当在水管中流动时,就可以从某个地方(例如自来水厂)源源不断地 ...

  4. node中的Readable - flowing/non-flowing mode

    大家都知道在node中Readable Stream有两种模式: flowing mode和non-flowing mode. 对于flowing mode的Readable Stream, 我们是没 ...

  5. 深入理解jQuery、Angular、node中的Promise

    最初遇到Promise是在jQuery中,在jQuery1.5版本中引入了Deferred Object,这个异步队列模块用于实现异步任务和回调函数的解耦.为ajax模块.队列模块.ready事件提供 ...

  6. Node.js 【Stream之笔记】

    从Node.js API文档中可知, 'A stream is an abstract interface implemented by various objects in Node. For ex ...

  7. jdk8中的stream

    https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/ Java 8 中的 Streams API 详解 Streams 的背景 ...

  8. node中异步IO的理解

    解释性语言和编译型语言的区别: 计算器不能直接的理解高级语言,只能理解机器语言,所以必须把高级语言翻译为机器语言,翻译的方式有两种,一个是编译,一个是解释. 解释性语言的程序不需要编译,它是在运行程序 ...

  9. Node.js:Stream(流)

    Stream 是一个抽象接口,Node 中有很多对象实现了这个接口.例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出). Node.js,Str ...

  10. 【Node.js】Stream(流)的学习笔记

    最近学习使用Node.js创建http proxy server,少不了要跟Stream打交道.昨天开始查阅一些资料,多少有了一些粗浅了解.整理在这里,供学习之用. 从Node.js API文档中可知 ...

随机推荐

  1. 【5分钟】W10 64bit系统本地安装postgresql 11

    1.下载 官网下载地址 2.安装 一路默认,有一个选语言的可以选中chinese simple(中文简体). 3.初始化 1)进入bin:   cd C:\Program Files\PostgreS ...

  2. Idea编译/运行Java程序慢

    修改前: 修改后: 参考: https://www.jjput.com/archives/macbookpro14m1mavenslowcompilation 问题 JDK尽量不要换版本 class ...

  3. Spring 中不得不了解的姿势

    说明 本文非原创,我只是进行了整理以及做了一些改动,仅供学习,若需进行商业使用,请联系原作者 原作者:苏三 原文链接:苏三说技术:Spring系列 Spring IOC 本章节解读的流程为Spring ...

  4. dbvisualizer不能执行pl/sql块

    如果是如下语句: begin          dbms_output.put_line('Hello World!'); end; 控制台会报错 解决方案:语句改写为如下 --/ begin    ...

  5. 记录--通过手写,分析axios核心原理

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.axios简介 axios是什么? Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中. ...

  6. 启用Windows防火墙后,FTP传输非常慢

    我们有一个计划任务,该任务使用Windows命令行FTP程序在两个Windows服务器之间传输大文件(〜130 MB).速度很慢(大约需要30分钟),有时会在传输完成之前终止.服务器是2003年(发送 ...

  7. Ubuntu系统部署springcloud+nacos遇到的问题。

    1,部署上的jar包运行正常,但是通过浏览器不能访问,telnet +IP+端口连接不通.小皮面板访问后台接口也是不通但是小皮面板可以通过浏览器访问.具体问题暂未解决. 2,改用docker部署,将j ...

  8. #倍增,floyd#CF147B Smile House

    题目 求一张有向图的最小正环(环上结点数最小) 分析 有环当且仅当 \(f[i][i]\) 为正数, 那么考虑跑 \(n\) 次 floyd 直接转移,时间复杂度为 \(O(n^4)\) 然而没必要这 ...

  9. #Splay#洛谷 1486 [NOI2004]郁闷的出纳员

    题目 分析 考虑加减工资直接打标记,查询第\(k\)多可以用平衡树, 删除有点恶心,这里考虑Splay,将需要删除的部分的后继splay到根节点并将左子树断边 代码 #include <cstd ...

  10. 开发人员使用HANA交付业务的学习路径

    本文于2019年7月22日完成,发布在个人博客网站上. 考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来. 入门 编程规范. 开发环境使用方法. 基本语法,与其它同类软件的 ...