stream API

1.stream模块

流:一组有序的、有起点和终点的字节数据的传输手段。在应用程序中各种对象之间交换与传输数据的时候,总是先将对象中所包含的数据转换为各种形式的流数据(即字节数据),在通过流的传输,到达目的对象后再将流转换为该对象中可以的数据。

对象流:所有使用 Node.js API 创建的流对象都只能操作 strings 和 Buffer(或 Uint8Array) 对象。但是,通过一些第三方流的实现,你依然能够处理其它类型的 JavaScript 值 (除了 null,它在流处理中有特殊意义)。 这些流被认为是工作在 “对象模式”(object mode)。

1.1原型只有一个pipe方法。

var Stream = require('stream');
//Stream { pipe: [Function] },  只有一个pipe方法。
console.log(Stream.prototype);

pipe()是管道流,监听的'data' 和'end'事件。通常我们用于从一个流中获取数据并将数据传递到另外一个流中,可以反压力机制来控制读写平衡。
如果要创建新的流对象实例,可以继承stream的API,如send模块定义SendStream的:
SendStream.prototype.__proto__ = Stream.prototype;

1.2类成员

  如下可知。它继承了EventEmitter.prototype,同时还包含四个流类型:读、写、可读写和可改变四个流,

var Stream = require('stream');
/*
//{ [Function: Stream]                
  super_:                              //静态成员变量,通过util.inherits(Stream,require('events').EventEmitter)继承EventEmitter中的属性和方法。
   { [Function: EventEmitter]          
     EventEmitter: [Circular],
     usingDomains: false,
     defaultMaxListeners: [Getter/Setter],
     init: [Function],
     listenerCount: [Function] },
  Readable: 
   { [Function: Readable]             //构造函数为Readable
     ReadableState: [Function: ReadableState],
     super_: [Circular],
     _fromList: [Function: fromList] },
  Writable: { [Function: Writable] WritableState: [Function: WritableState], super_: [Circular] },
  Duplex: 
   { [Function: Duplex]
     super_: 
      { [Function: Readable]
        ReadableState: [Function: ReadableState],
        super_: [Circular],
        _fromList: [Function: fromList] } },
  Transform: { [Function: Transform] super_: { [Function: Duplex] super_: [Object] } },
  PassThrough: { [Function: PassThrough] super_: { [Function: Transform] super_: [Object] } },
  Stream: [Circular] }·
*/
console.log(Stream);
 

Circular表示该属性包含循环引用:

A.EventEmitter = A
A.usingDomains = false
A.init = function() {

}
function C(){

}
C.a = C;
C.b = function B() {

}
C.super_ =  A

console.log(C);
/*
{ [Function: C]
  a: [Circular],
  b: [Function: B],
  super_: 
   { [Function: EventEmitter]
     EventEmitter: [Circular],
     usingDomains: false,
     init: [Function] } }
*

如 : Readable  可读流  fs.createReadStream()创建

        Writable    可写流 fs.createWriteStream()创建

        Duplex      可读写流 net.Socket创建流

        Transform 在读写过程中可以修改和变换数据的 Duplex 流 zlib.createDeflate创建,同时流又可以分成普通流、管道流和链接流(套接流)。

        看一个例子: 

var destroy = require('destroy')
var http = require('http')
var onFinished = require('on-finished')
 
http.createServer(function onRequest(req, res) {
    var stream = fs.createReadStream('package.json');
    //res为一个可写流,pipe为管道读写操作,是把源流输出到目标可写流
    //(writable)即把stream内容写入res
    stream.pipe(res) 
   //如果完成,触发销毁这个流,
   onFinished(res, function (err) {
       destroy(stream) 
    })
 });

扩展下程序:

var ReadStream = require('fs').ReadStream;
var fs = require('fs');
var ReadStream2 = require("stream");  //是一个抽象接口
var ReadStream3 = require("stream").Readable;

var http = require("http");
var a = new http.IncomingMessage();   //express中的req,它实现了可读流中的方法。
var b = fs.createReadStream('package.json');
//console.log("a",a);
console.log(a instanceof ReadStream);  //false
console.log(a instanceof ReadStream2); //true
console.log(a instanceof ReadStream3); //true 

console.log(b instanceof ReadStream);  //true
console.log(b instanceof ReadStream2); //true
console.log(b instanceof ReadStream3); //true 

 拷贝数据使用stream,参考:

http://www.cnblogs.com/bigbearbb/p/4210444.html

http://www.cnblogs.com/mtl-key/p/6426233.html

2. Readable接口

hash实现了Readable接口,监听readable事件。

const crypto = require('crypto');
const hash = crypto.createHash('sha256');
//'readable' 事件表明流有了新的动态:要么是有了新的数据,要么是到了流的尾部
hash.on('readable', () => {
  const data = hash.read();
  if (data) {
    console.log(data.toString('hex'));
    // Prints:
    //   6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
  }
});
// console.log("hash:",hash);
hash.write('some data to hash');
hash.end();     //触发readable事件
原文地址:https://www.cnblogs.com/liuyinlei/p/6918441.html