本文实例讲述了node.js使用stream模块实现自定义流。分享给大家供大家参考,具体如下:
有些时候我们需要自定义一些流,来操作特殊对象,node.js中为我们提供了一些基本流类。
我们新创建的流类需要继承四个基本流类之一(stream.Writeable,stream.Readable,stream.Duplex,stream.Transform),并确保调用了父类构造函数。
一、实现自定义的可读流
实现可读流需继承 stream.Readable,并实现 readable._read() 方法。
下面的代码我们实现了一个从数组中读取数据的流
const {Readable} = require('stream');
//这里我们自定义了一个用来读取数组的流
class ArrRead extends Readable {
constructor(arr, opt) {
//注意这里,需调用父类的构造函数
super(opt);
this.arr = arr;
this.index = 0;
}
//实现 _read() 方法
_read(size) {
//如果当前下标等于数组长度,说明数据已经读完
if (this.index == this.arr.length) {
this.push(null);
} else {
this.arr.slice(this.index, this.index + size).forEach((value) => {
this.push(value.toString());
});
this.index += size;
}
}
}
let arr = new ArrRead([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], {
highWaterMark: 2
});
//这样当我们监听 'data' 事件时,流会调用我们实现的 _read() 方法往缓冲区中读取数据
//然后提供给消费者
arr.on('data', function (data) {
console.log(data.toString());
});
二、实现自定义的可写流
实现可写流必须继承 stream.Writeable ,并实现 writeable._write() 方法。writable._writev() 方法是可选的。
const {Writable} = require('stream');
//这里我们自定义了一个用来写入数组的流
class ArrWrite extends Writable {
constructor(arr, opt) {
super(opt);
this.arr = arr;
}
//实现 _write() 方法
_write(chunk, encoding, callback) {
this.arr.push(chunk.toString());
callback();
}
}
let data = [];
let arr = new ArrWrite(data, {
highWaterMark: 3
});
arr.write('1');
arr.write('2');
arr.write('3');
console.log(data);
三、实现自定义的可读可写流
可读可写流必须继承 stream.Duplex,并实现 readable._read() 和 writable._write() 方法。
const {Duplex} = require('stream');
//这里我们自定义了一个用来写读可写数组的流
class ArrReadWrite extends Duplex {
constructor(arr, opt) {
super(opt);
this.arr = arr;
this.index = 0;
}
//实现 _write() 方法
_write(chunk, encoding, callback) {
this.arr.push(chunk.toString());
callback();
}
//实现 _read() 方法
_read(size) {
//如果当前下标等于数组长度,说明数据已经读完
if (this.index == this.arr.length) {
this.push(null);
} else {
this.arr.slice(this.index, this.index + size).forEach((value) => {
this.push(value.toString());
});
this.index += size;
}
}
}
let data = [];
let arrWR = new ArrReadWrite(data, {
highWaterMark: 3
});
//往流中写入数据
arrWR.write('1');
arrWR.write('2');
arrWR.write('3');
console.log(data);
//往流中读取数据
console.log(arrWR.read(2).toString());
console.log(arrWR.read(2).toString());
四、自定义的转换流
转换流必须继承 stream.Transform,需实现 transform._transform() 方法。
const {Transform} = require('stream');
//这里我们自定义了一个用来转换数组的流
class Trans extends Transform {
constructor(opt) {
super(opt);
}
_transform(chunk, encoding, callback) {
//将转换后的数据输出到可读流
this.push(chunk.toString().toUpperCase());
//参数一是Error对象
//参数二如果传入,会被转发到 readable.push()
callback();
}
}
let t = new Trans({
highWaterMark: 3
});
t.on('data', function (data) {
console.log(data.toString());
});
t.write('a');
t.write('b');
t.write('c');
转换流就是将读取到的数据做些计算然后输出。转换流既可以作为可读流,又可以作为可写流。
const {Transform} = require('stream');
//这里我们自定义了一个用来转换数组的流
class Trans extends Transform {
constructor(opt) {
super(opt);
}
_transform(chunk, encoding, callback) {
//将转换后的数据输出到可读流
this.push(chunk.toString().toUpperCase());
//参数一是Error对象
//参数二如果传入,会被转发到 readable.push()
callback();
}
}
let t = new Trans({
highWaterMark: 3
});
t.on('data', function (data) {
console.log('data', data.toString());
});
//stdin.pipe(t) 表示将我们的标准输入写入到我的转换流 t 中,此时 t 是可写流。
//pipe(process.stdout) 表示将转换流 t 中的数据读取到标准输出中,此时 t 是可读流。
process.stdin.pipe(t).pipe(process.stdout);
希望本文所述对大家node.js程序设计有所帮助。
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新动态
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]