有些时候我们需要自定义一些流,来操作特殊对象,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中通过stream模块实现自定义流的更多相关文章

  1. node.js中使用http模块创建服务器和客户端

    node.js中的 http 模块提供了创建服务器和客户端的方法,http 全称是超文本传输协议,基于 tcp 之上,属于应用层协议. 一.创建http服务器 const http = require ...

  2. node.js中path路径模块的使用

    path模块是node.js中处理路径的核心模块.可以很方便的处理关于文件路径的问题. join() 将多个参数值合并成一个路径 const path = require('path'); conso ...

  3. node.js中fs文件系统模块的使用

    node.js中为我们提供了fs文件系统模块,实现对文件或目录的创建,修改和删除等操作. fs模块中,所有的方法分为同步和异步两种实现. 有 sync 后缀的方法为同步方法,没有 sync 后缀的方法 ...

  4. Node.js 中的 stream

    什么是 stream Stream 借鉴自 Unix 编程哲学中的 pipe. Unix shell 命令中,管道式的操作 | 将上一个命令的输出作为下一个命令的输入.Node.js stream 中 ...

  5. Node.js权威指南 (12) - Node.js中的其他模块

    12.1 使用dns模块解析域名 / 313 12.1.1 使用resolve方法将域名解析为DNS记录 / 313 12.1.2 使用lookup方法查询IP地址 / 315 12.1.3 使用re ...

  6. 在node.js中使用mongose模块

    对象与文档相对应 创建项目目录,用root进入 # mkdir /home/test/part9/ 直接# npm install mongoose,报错如下 ../node_modules/nan/ ...

  7. node.js中使用zlib模块进行数据压缩和解压

    我们可以使用 zlib 模块来对数据进行压缩和解压处理,减小数据体积,加快传输速度. 一.通过创建转换流,对文件进行压缩和解压 const fs = require('fs'); const zlib ...

  8. 关于Node.js中的路径问题

    在前端学习过程中,涉及到路径的问题非常多,相对路径,绝对路径等.有时候明明觉得没问题,但是还是会出错.或者说线下没问题,但是到了线上就出现问题,因此弄懂路径问题,非常关键.我们需要知道为什么这个地方既 ...

  9. 初步揭秘node.js中的事件

    当你学习node.js的时候,Events是一个非常重要的需要理解的事情.非常多的Node对象触发事件,你能在文档API中找到很多例子.但是关于如何写自己的事件和监听,你可能还不太清楚.如果你不了解, ...

随机推荐

  1. laravel路由别名

    在定义路由时使用数组键 as 指定路由名称: Route::get('user/profile', ['as' => 'profile', function () { // }]); 另外,还可 ...

  2. hadoop完全分步式搭建

    实验环境介绍 4台机器,规划如下: 计算机名 IP地址 角色 master 192.168.138.200 NameNode,SecondaryNameNode,ResourceManager sla ...

  3. linux nodejs

    scp node-v8.15.0-linux-x64.tar.gz root@10.88.248.231:/lngoa tar -zxvf node-v8.15.0-linux-x64.tar.gz ...

  4. vue1 & vue2 数据驱动更新视图机制对比

    vue1 小粒度更新,精确追踪到数据变化所影响的dom变化,精确更新变化的dom 具体实现为,维护 observer watcher directive 三个类 ·observer负责监听数据变化,并 ...

  5. 20165312 2017-2018-2 《JAVA程序设计》第4周学习总结

    一.课本五六章知识点总结 1.第五章 继承是一种由已有的类创建新类的机制 子类继承父类的成员变量和方法 子类继承的方法只能操作子类继承和隐藏的成员变量 子类重写或新增的方法只能操作子类继承和新声明的成 ...

  6. Core Graphices 设置渐变

    Core Graphices 设置渐变 Quartz 提供了两种设置渐变的方式  CGShadingRef and CGGradientRef 尝试CGGradientRef 的使用 import & ...

  7. 使用睿云智合开源 Breeze 工具部署 Kubernetes v1.12.3 高可用集群

    一.Breeze简介 Breeze 项目是深圳睿云智合所开源的Kubernetes 图形化部署工具,大大简化了Kubernetes 部署的步骤,其最大亮点在于支持全离线环境的部署,且不需要FQ获取 G ...

  8. Android 开发 框架系列 EventBus 事件总线

    介绍 GitHub:https://github.com/greenrobot/EventBus 先聊聊EventBus 线程总线是干什么的,使用环境,优点.缺点. 干什么的? 一句话,简单统一数据传 ...

  9. Maven Return code is: 401

    maven 打包到仓库 需要配置认证: setting.xml <server><id>releases</id><username>admin< ...

  10. 二、Jmeter脚本开发

    目录 1.Jmeter协议录制 1.Jmeter协议录制 1.1 dboy进行录制 badboy下载地址:http://www.badboy.com.au/download/add badboy是一个 ...