Node.js中的stream

        上周学习了Buffer,而stream与Buffer是分不开的。今天来总结一下stream。stream模块可以通过以下方式引入,但对于只是简单在流中写入数据或从流中消费数据的应用来说,不需要直接实现流接口,也不需要进行下面的调用。

const stream = require('stream');

        Stream,顾名思义,就是“流”的意思。可以分为四种类型。

  1. Readable-可读流,负责读取外部的数据,并把数据缓存到内部的Buffer数组;
  2. Writable-可写流,负责消费数据,从可读流里面获取到数据,然后对得到的trunk数据块进行处理;
  3. Duplex-双工流,可读可写;
  4. Transform-转换流,可读可写,在读写过程中可以修改和变化数据,但不保存数据。

        可读流在工作中有两种模式:flowing和paused。初始时均为paused模式,必须显式调用read方法才能读取数据,可以通过监听‘data’事件或调用resume和pipe方法,切换到flowing模式。在flowing模式下,可以读取数据,并将数据提供给应用,可以通过调用pause和unpipe方法切换到paused模式。

        下面分别在例子中介绍一下可读流和可写流的常用事件。

var fs = require('fs');
var readStream = fs.createReadStream('read.jpg');
var n = 0;

readStream
	.on('data',function (chunk) {
		// 流将数据传递给消费者时触发(流转换到flowing模式时触发)
		console.log('data emits')
		//数据通过流传递时,是以buffer的格式传递的
		console.log(Buffer.isBuffer(chunk));
		//输出读取的文件内容
		//console.log(chunk.toString('utf8'))

		n++;
		//让流暂停
		readStream.pause()
		console.log('data pause');
		//定时器,模拟异步的处理
		setTimeout(function () {
			console.log('data pause end');
			//重新启动数据的传递
			readStream.resume()
		},10)
	})
	.on('readable', function () {
		// 流中有数据可供读取时触发(返回可用数据),当到达流数据尾部时,也会触发(返回null),触发顺序在‘end’之前
		console.log('data readable');
	})
	.on('end', function () {
		// 流中没有数据可提供消费时触发
		console.log('data ends')
		console.log(n);
	})
	.on('close', function () {
		// 流传输结束、关闭的时候触发,触发后,该流将不再触发任何事件。
		console.log('data close')
	})
	.on('error', function (e) {
		// 传输有错误时触发
		console.log('data read error' + e);
	})

        在上面的例子中,当数据读取的快,但写入较慢时就会出现问题,所以要判断数据写完后再继续读取,如下面的例子。

var fs = require('fs');
//创建一个可读流和一个可写流
var readStream = fs.createReadStream('old.JPG');
var writeStream = fs.createWriteStream('new.JPG');

readStream.on('data', function (chunk) {
	// 可写流的write方法向流中写入数据,返回布尔值,当流不在drain状态时,调用write会缓存数据块,并返回false,否则返回true。
	if(writeStream.write(chunk) === false){
		console.log('still cached')
		readStream.pause();    //pause方法使flowing模式的流停止触发‘data’事件,切出flowing模式,可用的数据保存在内部缓存中
	}
})

readStream.on('end', function(){
	writeStream.end();    //调用后表示接下来没有数据要被写入,再调用write方法会导致错误
})
//调用write方法返回false后,在恢复写入数据到流的时候触发
writeStream.on('drain',function(){
	console.log('data drain');
	//重新触发‘data’事件,切换到flowing模式
	readStream.resume();
})
        同时,可读流提供了更简单的方法实现上面的功能
var fs = require('fs');
//使用pipe方法,将可写流切换到flowing模式并将所有数据传给可写流,数据流被自动管理,即使可读流较快,可写流也不会超负荷
fs.createReadStream('old.JPG').pipe(fs.createWriteStream('new.JPG'));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值