最近准备用node中的stream操作文件,使用pipe方式做中间件.
在网上没有找到靠谱的例子和讲解.所以自己看源码折腾了下这块内容
stream
stream是针对数据流做抽象接口,ReadFileStream,WriteFileStream,httpserver中的req,res 都实现了这个接口.
由于stream将数据分割成段去操作所以不必担心程序占用大量内存导致内存溢出
stream下面有三个接口 Readable
, Writable
, Duplex
分别代表 读,写,可读可写
Duplex下有 Transform 接口 转换数据
pipe
管道,Readable做为开头,Writable作为目标,Transform做为中间件 自动读取数据 转换 产出
以下代码都是亲身体验过的
terminal输入一行 打印
process.stdin
.pipe(process.stdout);
terminal输入一行 转换为大写 打印
const toUpperTrans = Stream.Transform({
transform:function(chunk,encoding,cb){
this.push(chunk.toString().toUpperCase());
cb();
}
});
process.stdin
.pipe(toUpperTrans)
.pipe(process.stdout);
terminal输入一行 转换为大写 重复 打印
const toUpperTrans = Stream.Transform({
transform:function(chunk,encoding,cb){
this.push(chunk.toString().toUpperCase());
cb();
}
});
const duplateTrans = Stream.Transform({
transform:function(chunk,en,cb){
this.push(chunk.toString()+chunk.toString());
cb();
}
});
process.stdin
.pipe(toUpperTrans)
.pipe(duplateTrans)
.pipe(process.stdout);
terminal输入一行 转换为大写 重复 包裹 打印
const toUpperTrans = Stream.Transform({
transform:function(chunk,encoding,cb){
this.push(chunk.toString().toUpperCase());
cb();
}
});
const duplateTrans = Stream.Transform({
transform:function(chunk,en,cb){
this.push(chunk.toString()+chunk.toString());
cb();
}
});
function warpTrans(pre,suf){
return Stream.Transform({
transform:function(chunk,encoding,cb){
this.push(pre+chunk.toString()+suf);
cb();
}
});
}
process.stdin
.pipe(toUpperTrans)
.pipe(duplateTrans)
.pipe(warpTrans("(",")"))
.pipe(warpTrans("{","}"))
.pipe(process.stdout);
以上readble是process.stdin writeble是process.stdout也可以自定义readble,writeble
const Stream = require('stream').Stream;
var end_state = 10;
const diyRead = Stream.Readable({
read:function(n){
console.log("read");
console.log(end_state);
if(end_state==0){
this.push(null);
}else{
this.push(end_state+"");
end_state--;
}
}
});
const diyWrite = Stream.Writable({
write:function(chunk,encodeing,onwrite){
console.log("write");
console.log(chunk.toString());
onwrite();
}
});
const toUpperTrans = Stream.Transform({
transform:function(chunk,encoding,cb){
this.push(chunk.toString().toUpperCase());
cb();
}
});
const duplateTrans = Stream.Transform({
transform:function(chunk,en,cb){
this.push(chunk.toString()+chunk.toString());
cb();
}
});
function warpTrans(pre,suf){
return Stream.Transform({
transform:function(chunk,encoding,cb){
this.push(pre+chunk.toString()+suf);
cb();
}
});
}
diyRead
.pipe(toUpperTrans)
.pipe(duplateTrans)
.pipe(warpTrans("(",")"))
.pipe(warpTrans("{","}"))
.pipe(diyWrite);
吐槽的地方
源码中使用类(this)+回掉+protype+以及各种状态和下划线开头的变量组织代码 代码很难看.逻辑不清晰.
pipe的设计 readble开头 writeble结尾 transform中间部分区分太细 我觉得不做区分会更好