stream模块分类介绍

流是一个抽象接口,在 Node 里被不同的对象实现。比如HTTP 服务器request和response对象都是流。

Stream分类

在nodejs中,有四种stream类型:

  • Readable:用来读取数据,比如 fs.createReadStream()可读流。
  • Writable:用来写数据,比如 fs.createWriteStream()可写流。
  • Duplex:可读+可写,比如 net.Socket()。
  • Transform:在读写的过程中,可以对数据进行修改,比如 zlib.createDeflate()(数据压缩/解压)。

Readable流

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目的地断开这一对象。

let fs = require('fs');
// 读取的时候默认读 默认64k,encoding 读取默认都是buffer
let rs = fs.createReadStream('./2.txt', {
  highWaterMark: 3, // 字节
  flags:'r',
  autoClose:true, // 默认读取完毕后自动关闭
  start:0,
  //end:3,// 流是闭合区间 包start也包end
  encoding:'utf8'
});
// 默认创建一个流 是非流动模式,默认不会读取数据
// 我们需要接收数据 我们要监听data事件,数据会总动的流出来
rs.on('error',function (err) {
  console.log(err)
});
rs.on('open',function () {
  console.log('文件打开了');
});
// 内部会自动的触发这个事件 rs.emit('data');

rs.on('data',function (data) {
  console.log(data);
  rs.pause(); // 暂停触发on('data')事件,将流动模式又转化成了非流动模式
});
setTimeout(()=>{rs.resume()},5000)
rs.on('end',function () {
  console.log('读取完毕了');
});
rs.on('close',function () {
  console.log('关闭')
});
复制代码

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为目的地时发出。

let fs = require('fs');
let ws = fs.createWriteStream('./2.txt', {
  flags: 'w', // 默认文件不存在会创建
  highWaterMark: 1, // 设置当前缓存区的大小
  encoding: 'utf8', // 文件里存放的都是二进制
  start: 0,
  autoClose: true, // 自动关闭
  mode: 0o666, // 可读可写
});
// drain的触发时机,只有当highWaterMark填满时,才可能触发drain
let i = 9;
function write() {
  let flag = true;
  while (flag && i >= 0) {
    i--;
    flag = ws.write('111'); // 987 // 654 // 321 // 0
    console.log(flag)
  }
}
write();
ws.on('drain', function () {
  console.log('干了');
  write();
});
复制代码

Duplex(双工流)

有了双工流,我们可以在同一个对象上同时实现可读和可写,就好像同时继承这两个接口。 重要的是双工流的可读性和可写性操作完全独立于彼此。这仅仅是将两个特性组合成一个对象。

let fs = require('fs');
let { Duplex } = require('stream');
class MyDuplex extends Duplex{
  _read(){
    this.push('hello');
    this.push(null);
  }
  _write(chunk,encoding,callback){
    console.log(chunk);
    callback();
  }
}
let r = new MyDuplex();
r.on('data',function (data) {
    console.log(data);
});
r.write('hello');
复制代码

Transform(转换流)

Transform stream是Duplex stream的特例,也就是说,Transform stream也同时可读可写。跟Duplex stream的区别点在于,Transform stream的输出与输入是存在相关性的。

let fs = require('fs');
let { Transform } = require('stream');
class T1 extends Transform{
  _transform(chunk,encoding,callback){
    this.push('123');
    this.push(null);
    callback();
  }
}
let t = new T1();
t.on('readable',function (data) {
    console.log(123123)
    console.log(data);
});
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值