浅谈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, 加油

    

 

    愿得一人心 白首不相离

    

 

 

 

 

  

转载于:https://www.cnblogs.com/yangshuaiGo/p/6381218.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值