浅谈stream数据流

汴水流,泗水流,流到瓜州古渡头, 吴山点点愁。 我们知道水是源源不断的, 抽刀断水水更流, 斩不断, 理还乱, 是水流。(技术贴, 本文权当读者没学过古诗).
在一些语言里, 我们的前辈把数据当成水流, 于是有了数据流的说法~ 很贴切, 也很好理解。 今天呢, 我们就一起来看看node.js里面的stream数据流。
stream是一个抽象的接口, node里有很多对象实现了这个接口, 如: 对http服务器发起请求的request对象就是一个Stream, 还有stdout(标准输出);
node.js Stream有四种流类型:
1) Readable 可读操作
2) Writable 可写操作
3) Duplex 可读可写操作
4) Transform 操作被写入数据, 然后读出结果(大致是说, 你把数据载入我的方法里, 我帮你处理后再返回给你)
而且所有的stream 都是Events 对象的实例, 也就是说可以直接添加各种监听事件哈~ 常用的stream流的事件有:
1) data 当有数据可读时候触发
2) end 没有更多数据可读时触发
3) erroe 在接收和写入过程中发生错误时触发
4) finish 所有数据已被写入时触发 (写入操作时候用)
好了, 那我们简单说下怎么从流重读取数据, 创建love.txt, 内容如下: 这不是一封情书: i love ~ ♥
创建readStream.js 文件
var fs = require("fs");
var data = ''; // 定义data 接收数据
// 创建可读流
var readerStream = fs.createReadStream('love.txt');
// 设置编码为 utf8。
readerStream.setEncoding('UTF8'); // 其实默认就是utf8 去掉也无妨, 这里只是为了小伙伴们知道怎么去指定编码
// 处理流事件 --> data, end, and error
readerStream.on('data', function(chunk) { // chunk 是一种数据传输机制, 把数据流分成小块输出过来
data += chunk;
});
readerStream.on('end',function(){ // 必须数据传输完成后 才能打印出data
console.log(data);
});
readerStream.on('error', function(err){
console.log(err.stack);
});
console.log("程序执行完毕");
运行结果如下
程序执行完毕
这不是一封情书: i love ~ ♥
成功读取到文件内容, 那么怎么去写入内容呢
var fs = require("fs");
var data = '杨帅要写入的内容';
// 创建一个可以写入的流,写入到文件 output.txt 中
var writerStream = fs.createWriteStream('output.txt');
// 使用 utf8 编码写入数据
writerStream.write(data,'UTF8');
// 写完后停止写入
writerStream.end();
// 处理流事件 --> data, end, and error
writerStream.on('finish', function() {
console.log("写入完成");
});
writerStream.on('error', function(err){
console.log(err.stack); // 打印错误信息
});
console.log("程序执行完毕");
跑一下
然后查看目录里, 多了一个output.txt的文件, 文件内容为:
杨帅要写入的内容
符合预期, 可是代码不够优雅, 也不够精简, 那么有更简单的方法么, 有!
node里面提供了一个输出流到输入流的机制(pipe) , 俗称管道流。 有了这个小玩意儿, 可以事半功倍哦(而且还有一些防止读入过快, 写入过慢, 也就是俗称爆仓的功效)。麻雀虽小五脏俱全!
ok, 有了它 , 画风是这样的
// 十分好用的管道流
var fs = require('fs');
var readFile = fs.createReadStream('love.txt'); var writeFile = fs.createWriteStream('copy-input.txt'); // 创建可写流 并写入copy-input.txt readFile.pipe(writeFile); console.log('数据传输完成');
看起来很甜美的代码, 运行测试一下
果然出现了一个copy-input.txt的文件M 内容为
这不是一封情书: i love ~ ♥
链式流
我们知道, 管道不一定是直达的, 那么我们怎么达到我们的目标点呢。 当然是接水管呀~
在node里, 我们可以通过链式的方法来对数据进行一些中间层的操作。
此时我们实现一个文件的压缩和解压的demo 来体验一下, 代码里会有详细的注释。
var fs = require('fs');
var zlib = require('zlib'); //压缩和解压文件模块
// 比如我们要把love.txt 压缩成 yangshuai.zzzz
// 先读取love.txt
fs.createReadStream('love.txt')
.pipe(zlib.createGzip()) // zlib.createGzip()是压缩文件的方法 这是一个transform流, 我们前面说过transform可以操作被写入数据, 然后读出结果
.pipe(fs.createWriteStream('yangshuai.zzzz'));
console.log('看起来很严谨, 很nice');
运行一下

然后看目录

果不其然, 这个压缩文件已经创建成功~ 可是打开都是二进制编码 宝宝看不懂怎么办~
没关系, 我们来解压一下
var fs = require('fs');
var zlib = require('zlib'); //压缩和解压文件模块
// 比如我们要把 yangshuai.zzzz 解压成 yangshuai.txt(为了区分, 不用love.txt)
// 先读取yangshuai.zzzoz
fs.createReadStream('yangshuai.zzzz')
.pipe(zlib.createGunzip()) // zlib.createGzip()是压缩文件的方法 这是一个transform流
.pipe(fs.createWriteStream('yangshuai.txt'));
console.log('这段解压代码看起来也很严谨, 也很nice');


是不是操作起来很方便呢~
ok, stream 数据流我们就说到这里。小伙伴们有没有明了呢~
欢迎指正~ 期待一起进步 2017, 加油

愿得一人心 白首不相离
浅谈stream数据流的更多相关文章
- 浅谈React数据流管理
引言:为什么数据流管理如此重要?react的核心思想就是:UI=render(data),data就是我们说的数据流,render是react提供的纯函数,所以用户界面的展示完全取决于数据层.这篇文章 ...
- 浅谈iOS视频开发
浅谈iOS视频开发 这段时间对视频开发进行了一些了解,在这里和大家分享一下我自己觉得学习步骤和资料,希望对那些对视频感兴趣的朋友有些帮助. 一.iOS系统自带播放器 要了解iOS视频开发,首先我们从 ...
- 浅谈 Requests包
浅谈 Requests包 一:Requests包是做什么的? 简单地说,是用python处理HTTP的一个包. 它的标志也非常有气质,是一个双蛇杖,按照官方的说法,一条蛇代表client,一条代表se ...
- 浅谈angular2+ionic2
浅谈angular2+ionic2 前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别. 1. 项目所用:angular2+ionic2 ...
- .NET(C#):浅谈程序集清单资源和RESX资源
原文:.NET(C#):浅谈程序集清单资源和RESX资源 目录 程序集清单资源 RESX资源文件 使用ResourceReader和ResourceSet解析二进制资源文件 使用ResourceM ...
- 浅谈Vue不同场景下组件间的数据交流
浅谈Vue不同场景下组件间的数据“交流” Vue的官方文档可以说是很详细了.在我看来,它和react等其他框架文档一样,讲述的方式的更多的是“方法论”,而不是“场景论”,这也就导致了:我们在阅读完 ...
- 【ASP.NET MVC系列】浅谈ASP.NET MVC八大类扩展(上篇)
lASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操 ...
- 浅谈一下mshta在CVE-2017-11882里的命令构造
Evi1cg同学前不久放出CVE-2017-11882的一个 python利用脚本,地址在https://github.com/Ridter/CVE-2017-11882/,不过其中一个版本里边有一个 ...
- 浅谈 DDoS 攻击与防御
浅谈 DDoS 攻击与防御 原创: iMike 运维之美 什么是 DDoS DDoS 是英文 Distributed Denial of Service 的缩写,中文译作分布式拒绝服务.那什么又是拒 ...
随机推荐
- RAC(ReactiveCocoa)
什么是 ReactiveCocoa ReactiveCocoa(其简称为 RAC)是由 Github 开源的一个应用于 iOS 和 OS X 开发的新框架.RAC 具有函数式编程和响应式编程的特性.它 ...
- POJ3259负环判定
题意:有n个顶点,m条边,然后有w个洞,过每个洞的时间为-ti,求是否会时光倒流 分析:就是求是否存在负圈,用Bellman-Floyd判定是否存在负圈即可,注意是无向图,所以路径是双向可达的 #in ...
- lpc1768的PWM使用
//p2.0 pwm1.1 void ALS_Init(void) //初始化 { LPC_SC->PCONP |= (1<<1)|(1<<2)|(1<&l ...
- 全方位分析Objcetive-C Runtime 分类: ios技术 2015-03-11 22:29 77人阅读 评论(0) 收藏
本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的动态特性,使这门古老的语言焕发生机.主要内容如下: 引言 简介 与Runtime交互 ...
- Treap初步
模板题 bzoj3224: Tyvj 1728 普通平衡树 #include <bits/stdc++.h> #define rep(i, a, b) for (int i = a; i ...
- mysql5.7.10和mysql5.5.39两个版本对于group by函数的处理差异
原理还是没有搞清楚,在官网上看了一下,看的不是很清楚.一并都记录一下. 问题描述: 存在如下数据结构 sql: 求用户最近更新的那条记录 思路: 按照modify_time排序后按照user_id分组 ...
- hisi出的H264码流结构
hisi出的H264码流结构: IDR帧结构如下: 开始码 + nalu + I帧 + 开始码 + nalu + SPS + 开始码 + nalu + PPS + ...
- Oracle的一些命令
sqlldr: 一般用于导入以任何后缀结束的文件,我这次就是因为要导入一张以.20160101为后缀的文件,当初简直束手无策 结合input.ctl使用,可以在DOS下使用,可以对一张表导入数十万,百 ...
- 除trigger()方法外的jquery手动触发事件
trigger()可以触发指定事件是大家基本都知道的了. 除了trigger()之外我们也可以这样来触发: html <div id="box" style="he ...
- 一个参数引起的mysql从库宕机血案
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://suifu.blog.51cto.com/9167728/1859252 一个参数 ...