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);
'data'
和'end'
事件。通常我们用于从一个流中获取数据并将数据传递到另外一个流中,可以反压力机制来控制读写平衡。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事件