node.js中的流

node.js中的流是一种数据传输手段,流是有顺序的。流不关心整体流程,只管取出数据,获取数据后的操作

流有四种基本的类型

Readable - 可读的流 (例如 fs.createReadStream()). 

Writable - 可写的流 (例如 fs.createWriteStream()).

Duplex - 可读写的流 (例如 net.Socket). 

Transform - 在读写过程中可以修改和变换数据的 Duplex 流 (例如 zlib.createDeflate()).

可读流有两种模式

flowing 流动模式

paused 暂停模式

流动模式:flowing 没有缓存区。读一点数据,发射一点数据。当数据全部读完了触发一个end事件。例如:pipe(),resume()方法不走缓存.

data事件,当你一旦开始监听data事件的时候,流就可以读文件的内容并且发射data 。默认请况下,当你监听data事件之后,会不停的读数据,然后触发data事件,触发完data事件后再次读数据。

let rs=fs.createReadStream('./11.txt',{

    highWaterMark:3

});

rs.setEncoding('utf8');rs.on('data',function(data){

    //data获取到的是个buffer,要想获取字符需要设置编码

    console.log(data);

});

rs.on('end',function(){

    console.log('文件读完了');

});

pipe是可读流 的方法

ReadStream.prototype.pipe = function (dest) {

    this.on('data', (data)=>{

        let flag = dest.write(data);//写入数据,返回true,说明缓存区没满还可以继续写。返回

        false暂停一下。监听drain事件,等到触发drain事件说明数据消化完了,再继续读取数据

        if(!flag){

            this.pause();

        }

    });

    dest.on('drain', ()=>{

        this.resume();

    });

    this.on('end', ()=>{

        dest.end();

    });

}

ReadStream.prototype.pause = function(){

    this.flowing = false;

}

ReadStream.prototype.resume = function(){

    this.flowing = true;

    this.read();

}

dest 数据写入目标

可以在单个可读流上绑定多个可写流。

const r = fs.createReadStream('file.txt');

const z = zlib.createGzip();

const w = fs.createWriteStream('file.txt.gz');

r.pipe(z).pipe(w);

暂停模式:paused (初始化模式) 内部设置一个缓存区,缓存区默认大小64kb.实际大小以highWaterMark的值为准。当你监听 readable事件的时候,会进入暂停模式。读取highWaterMark的值放入缓存区,触发readable事件。

let fs = require('fs');

let rs = fs.createReadStream('./1.txt',{

    highWaterMark:3

});

rs.on('readable',()=>{

  onsole.log(rs._readableState.length);//3

  let ch = rs.read(1);

  //当你读了一个字节后,发现只剩下2个字节,不够highWaterMark,会再次读取highWaterMark个字节并填到

缓存区内

      console.log(rs._readableState.length);//2

      let ch = rs.read(3);

      setTimeout(()=>{

          console.log(rs._readableState.length);//5

      },200)

});

自定义流

let {Writable,Readable,Duplex,Transform} = require('stream');

自定义可读流

为了实现可读流,引用Readable接口并用它构造新对象。

    我们可以直接把供使用的数据push出去。

    当push一个null对象就意味着我们想发出信号——这个流没有更多数据了。

var stream = require('stream');

var util = require('util');

util.inherits(Counter, stream.Readable);

function Counter(options) {

    stream.Readable.call(this, options);

    this._index = 0;

}

Counter.prototype._read = function() {

    if(this._index++<3){

        this.push(this._index+'');

    }else{

        this.push(null);

    }

};

var counter = new Counter();

counter.on('data', function(data){

    console.log("读到数据: " + data.toString());//no maybe

});

counter.on('end', function(data){

    console.log("读完了");

});

自定义可写流

为了实现可写流,我们需要使用流模块中的Writable构造函数。 我们只需给Writable构造函数传递一些选项并创建一个对象。唯一需要的选项是write函数,该函数揭露数据块要往哪里写。

1.chunk通常是一个buffer,除非我们配置不同的流。

2.encoding是在特定情况下需要的参数,通常我们可以忽略它。

3.callback是在完成处理数据块后需要调用的函数。这是写数据成功与否的标志。若要发出故障信号,请用错误对象调用回调函数

var stream=require('stream');

var util=require('util');

util.inherits(Writer,stream.Writable);

letstock=[];

function Writer(opt) {

stream.Writable.call(this,opt);

}

Writer.prototype._write=function(chunk,encoding,callback) {

setTimeout(()=>{

stock.push(chunk.toString('utf8'));

console.log("增加: "+chunk);

callback();

},500)

};

var w=newWriter();

for(vari=1;i<=5;i++){

w.write("项目:"+i,'utf8');

}

w.end("结束写入",function(){

console.log(stock);

});

双工流

双工流(可读可写流)是可读流和可写流的实现。例如:net.Socket

let {Duplex} = require('stream');

let index = 0;

let s = Duplex({

    read(){

        if(index++<3)

          this.push('a');

          else

      this.push(null); 

    },

    write(chunk,encoding,cb){

      console.log(chunk.toString().toUpperCase());

      cb();

    }

});

//process.stdin 标准输入流

//proces.stdout标准输出流

process.stdin.pipe(s).pipe(process.stdout);

Transform转换流

转换流是实现数据转换的,(可读流可写流)只能实现一种。

let {Transform} = require('stream');

let t = Transform({

    transform(chunk,encoding,cb){

        this.push(chunk.toString().toUpperCase());

        cb();

    }

});

process.stdin.pipe(t).pipe(process.stdout);

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容

  • stream 流是一个抽象接口,在 Node 里被不同的对象实现。例如 request to an HTTP se...
    明明三省阅读 3,384评论 1 10
  • Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 众所周知,在Netscape设计出JavaScri...
    w_zhuan阅读 3,606评论 2 41
  • //公共引用 varfs =require('fs'), path =require('path'); 1、读取文...
    才気莮孒阅读 824评论 0 1
  • STEP: Prerequist: (1) NodeJS: download the latest version...
    于恺雯阅读 529评论 0 1
  • ★★★,#蝴蝶效应#讲真,这片子为什么评分这么高?难道是因为它是第一个表现这个理论的片子 ?除了结局擦肩而过有点戳...
    辰时晴空阅读 658评论 0 1