当前位置: 首页 > news >正文

浅谈node中的流stream(一)

简单介绍流

一般处理数据有两种模式, buffer模式和stream模式, buffer模式就是取完数据一次性操作, stream模式就是边取数据边操作.

例如如果打开一个8G的文件, 用buffer模式就是先分配2G的内存, 把文件全部读出来, 然后开始操作内存, 而用流模式的方法就是边读数据, 边开始处理.

从这里看出stream模式无论是在空间和时间上都优于buffer模式:在空间上, 内存只会占用当前需要处理的一块数据区域的大小, 而不是整个文件.在时间上, 因为不需要全部的数据就可以开始处理, 时间就相当于节约了, 从串行变成了并行操作(这里的并行不是多线程的并行, 而是生产者和消费者并行).

美团在流的进阶篇中就有介绍其作用的一个实例

const fs = require('fs');
fs.readFile(file, function (err, body) {
        console.log(body);
        console.log(body.toString());
})
复制代码

然后如果文件过大就会出现如下情况


报错的原因是body这个Buffer对象的长度过大,导致toString方法失败。

可见,这种一次获取全部内容的做法,不适合操作大文件。

可以考虑使用流来读取文件内容。

const fs = require('fs');
fs.createReadStream(file).pipe(process.stdout);
复制代码

fs.createReadStream创建一个可读流,连接了源头(上游,文件)和消耗方(下游,标准输出)。


还有一个好处就是链式调用, 也就是可组合操作, 大大增加了代码的可重用性.比如下面这个代码(中间的pipe可以很方便的增删):

fs.createReadStream(file)
        .pipe(zlib.createGzip())
        //.pipe(crypto.createCipher('aes192', 'secret'))
        .pipe(req) .on('finish', function() {
        console.log('File succesfully sent');
});
复制代码

深入了解

后面的介绍会涉及到下面的3各方面,今天只详细解读第一部分

1.流的基本类型,以及Stream模块的基本使用方法

2.流式处理与back pressure的工作原理

3.如何开发流式程序,包括对Gulp与Browserify的剖析,以及一个实战示例。

流的四种类型

Stream提供了以下四种类型的流:

var  Stream =require('stream')
var  Readable = Stream.Readable
var  Writable = Stream.Writable
var  Duplex = Stream.Duplex
var  Transform = Stream.Transform
复制代码

使用Stream可实现数据的流式处理,如:

var fs = require('fs')
// `fs.createReadStream`创建一个`Readable`对象以读取`bigFile`的内容,并输出到标准输出
// 如果使用`fs.readFile`则可能由于文件过大而失败
fs.createReadStream(bigFile).pipe(process.stdout)
复制代码

Readable:创建可读流。

Writable:创建可写流。

Duplex:创建可读可写流。

Transform:在Transform中可写端写入的数据经变换后会自动添加到可读端。

(详细例子可以参考如下流-基础篇-美团)


今天先到这里,后面第二篇会详细讲解到流背后的工作原理,以及如何实现流式数据处理和back presure机制

参考:

Node.js流模式编程详解

流-基础篇-美团

流-进阶篇-美团

流-实战篇-美团



转载于:https://juejin.im/post/5a74aa265188254e76177fb3

相关文章:

  • 源码解读之ArrayList
  • FIR基本型仿真_03
  • springboot(十九):使用Spring Boot Actuator监控应用
  • Spring源码系列:依赖注入(四)-总结
  • react native android 真机调试
  • WeexConf 2018干货系列|Weex + Ui
  • CSS最常用的三种选择器
  • GridView中使用CheckBox
  • 使用Python读写csv文件的三种方法
  • jdk动态代理使用及原理
  • mariadb/mysql使用Navicat连接报错
  • 【10】万魂杀服务器开发之特性 条件触发器(Condition Trigger)机制
  • 【Lv1-Lesson007】Where Are You From?
  • 写一个H5___type:range__调色板
  • React 组件生命周期
  • hexo+github搭建个人博客
  • IDEA 插件开发入门教程
  • JavaScript设计模式与开发实践系列之策略模式
  • js中的正则表达式入门
  • npx命令介绍
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • SQLServer之索引简介
  • 技术:超级实用的电脑小技巧
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 普通函数和构造函数的区别
  • 区块链技术特点之去中心化特性
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • # 达梦数据库知识点
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #、%和$符号在OGNL表达式中经常出现
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (arch)linux 转换文件编码格式
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)计算机毕业设计ssm电影分享网站
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (区间dp) (经典例题) 石子合并
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET 材料检测系统崩溃分析
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .netcore 获取appsettings
  • :“Failed to access IIS metabase”解决方法
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • @property @synthesize @dynamic 及相关属性作用探究
  • [04] Android逐帧动画(一)
  • [20171101]rman to destination.txt
  • [20171102]视图v$session中process字段含义
  • [2018][note]用于超快偏振开关和动态光束分裂的all-optical有源THz超表——
  • [20181219]script使用小技巧.txt
  • [ACL2022] Text Smoothing: 一种在文本分类任务上的数据增强方法