• Node.js数据流Stream之Readable流和Writable流


    一、前传

    Stream在很多语言都会有,当然Node.js也不例外。数据流是可读、可写、或即可读又可写的内存结构。Node.js中主要包括Readable、Writable、Duplex(双工)和Transform(变换)流。但是在学这些之前先学会util模块中的一个从其他对象继承的功能.

    util模块提供了util.inherits()方法来允许你创建一个继承另一个对象的prototype(原形)方法的对象。当创建一个新对象时,prototype方法自动被使用。

    util.inherits(constructor,superconstructor)原形constructor被设定为原形superConstructor,并在一个新的对象被创建时执行。可以通过使用constructor.super_属性从自定义对象的构造函数访问supercontructor.

    二、Readable流

    有的前传util模块从其他对象继承的功能的了解,Readable就很好理解了.主要它包含以下方法和事件。

    1.事件:

    readable:在数据块可以从流中读取的时候发出。

    data:类似readable,不同之处在于,当数据的事件处理程序被连接时,流被转变成流动的模式,并且数据处理程序被连续的调用,直到所有数据都被用尽

    end:当数据不再被提供时由流发出

    close:当底层资源,如文件,已关闭时发出。

    error:在接收数据中出错是发出。

    2.方法:

    read([size]):从流中读数据.数据可以是String、Buffer、null(下面代码会有),当指定size,那么只读仅限于那个字节数

    setEncoding(encoding):设置read()请求读取返回String时使用的编码

    pause():暂停从该对象发出的data事件

    resume():恢复从该对象发出的data事件

    pipe(destination,[options]):把这个流的输出传输到一个由deatination(目的地)指定的Writable流对象。options是一个js对象.例如:{end:true}当Readable结束时就结束Writable目的地。

    unpipe([destination]):从Writale目的地断开这一对象。

    3.demo:

    var stream = require('stream');
    var util = require('util');
    util.inherits(Answers, stream.Readable);
    function Answers(opt) {
      stream.Readable.call(this, opt);
      this.quotes = ["yes", "no", "maybe"];
      this._index = 0;
    }
    Answers.prototype._read = function() {
      if (this._index > this.quotes.length){
        this.push(null);
      } else {
        this.push(this.quotes[this._index]);
        this._index += 1;
      }
    };
    var r = new Answers();
    console.log("Direct read: " + r.read().toString());
    r.on('data', function(data){
      console.log("Callback read: " + data.toString());
    });
    r.on('end', function(data){
      console.log("No more answers.");
    });
    r.on('readable',function(data)
    {
       console.log('readable');
    });
    "C:Program Files (x86)JetBrainsWebStorm 11.0.3in
    unnerw.exe" F:
    odejs
    ode.exe stream_read.js
    Direct read: yes
    readable
    Callback read: no
    Callback read: maybe
    readable
    readable
    readable
    No more answers.
    
    Process finished with exit code 0

    上面定义了一个通过util.inherits()继承Readable流的对象,从输出结果可以看到输出了3个字符串,但readable事件确执行了4次,其实前面也有写,read()可以是null,最后是push(null)了。

    三、Writable流

    有读就会有写,毕竟是可逆的,它和readable一样也有一些事件和方法

    1.方法

    write(chunk,[encoding],[callback]):将数据写入流。chunk(数据块)中包含要写入的数据,encoding指定字符串的编码,callback指定当数据已经完全刷新时执行的一个回调函数。如果成功写入,write()返回true.

    end([chunk],[encoding],[callback]):与write()相同,它把Writable对象设为不再接受数据的状态,并发送finish事件。

    2.事件

    drain:在write()调用返回false后,当准备好开始写更多数据时,发出此事件通知监视器。

    finish:当end()在Writable对象上调用,所以数据被刷新,并不会有更多的数据被接受时触发

    pipe:当pipe()方法在Readable流上调用,已添加此writable为目的地时发出

    unpipe:当unpipe()方法被调用,以删除Writable为目的地时发出。

    3.demo

    var stream = require('stream');
    var util = require('util');
    util.inherits(Writer, stream.Writable);
    function Writer(opt) {
      stream.Writable.call(this, opt);
      this.data = new Array();
    }
    Writer.prototype._write = function(data, encoding, callback) {
      this.data.push(data.toString('utf8'));
      console.log("Adding: " + data);
      callback();
    };
    var w = new Writer();
    for (var i=1; i<=5; i++){  
      w.write("Item" + i, 'utf8');
    }
    w.end("ItemLast");
    console.log(w.data);
    "C:Program Files (x86)JetBrainsWebStorm 11.0.3in
    unnerw.exe" F:
    odejs
    ode.exe stream_write.js
    Adding: Item1
    Adding: Item2
    Adding: Item3
    Adding: Item4
    Adding: Item5
    Adding: ItemLast
    [ 'Item1', 'Item2', 'Item3', 'Item4', 'Item5', 'ItemLast' ]
    
    Process finished with exit code 0

    四、把Readable流用管道输送到Writable流

    上面也介绍了Readable流pipe()方法,这个主要是来测试

    var stream = require('stream');
    var util = require('util');
    util.inherits(Reader, stream.Readable);
    util.inherits(Writer, stream.Writable);
    function Reader(opt) {
      stream.Readable.call(this, opt);
      this._index = 1;
    }
    Reader.prototype._read = function(size) {
      var i = this._index++;
      if (i > 10){
        this.push(null);
      } else {
        this.push("Item " + i.toString());
      }
    };
    function Writer(opt) {
      stream.Writable.call(this, opt);
      this._index = 1;
    }
    Writer.prototype._write = function(data, encoding, callback) {
      console.log(data.toString());
      callback();
    };
    
    var r = new Reader();
    var w = new Writer();
    w.on('pipe',function(){
      console.log('pipe');
    });
    r.pipe(w);
    "C:Program Files (x86)JetBrainsWebStorm 11.0.3in
    unnerw.exe" F:
    odejs
    ode.exe stream_piped.js
    pipe
    Item 1
    Item 2
    Item 3
    Item 4
    Item 5
    Item 6
    Item 7
    Item 8
    Item 9
    Item 10
    
    Process finished with exit code 0
  • 相关阅读:
    Java 注解指导手册(下)
    CentOS安装Redis Sentinel HA集群
    EasyBCD安装CentOS双系统
    读《大型网站技术架构核心原理与案例分析》
    CentOS的Redis内存分配策略配置
    CentOS搭建VSFTP
    freemaker分页备忘
    jenkins持续集成配置备忘
    Redis常用命令
    stream转byte数组几种方式
  • 原文地址:https://www.cnblogs.com/5ishare/p/5299493.html
Copyright © 2020-2023  润新知