gpt4 book ai didi

node.js - 从两个管道流创建 Node.js 流

转载 作者:IT老高 更新时间:2023-10-28 22:11:42 27 4
gpt4 key购买 nike

如果可能的话,我想通过管道将两个 Node.js 流合并为一个。我正在使用 Transform流。

换句话说,我希望我的库返回 myStream 供人们使用。例如,他们可以写:

process.stdin.pipe(myStream).pipe(process.stdout);

在内部,我正在使用第三方 vendorStream 来完成一些工作,插入到 myInternalStream 中包含的我自己的逻辑中。所以上面的内容将转化为:

process.stdin.pipe(vendorStream).pipe(myInternalStream).pipe(process.stdout);

我可以这样做吗?我试过 var myStream = vendorStream.pipe(myInternalStream) 但这显然行不通。

为了类比 bash,假设我想编写一个程序来检查字母 h 是否出现在某个流的最后一行(tail -n 1 | grep h),我可以创建一个shell脚本:

# myscript.sh
tail -n 1 | grep h

然后如果人们这样做:

$ printf "abc\ndef\nghi" | . myscript.sh

它只是工作。

这是我目前所拥有的:

// Combine a pipe of two streams into one stream

var util = require('util')
, Transform = require('stream').Transform;

var chunks1 = [];
var stream1 = new Transform();
var soFar = '';
stream1._transform = function(chunk, encoding, done) {
chunks1.push(chunk.toString());
var pieces = (soFar + chunk).split('\n');
soFar = pieces.pop();
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
this.push(piece);
}
return done();
};

var chunks2 = [];
var count = 0;
var stream2 = new Transform();
stream2._transform = function(chunk, encoding, done) {
chunks2.push(chunk.toString());
count = count + 1;
this.push(count + ' ' + chunk.toString() + '\n');
done();
};

var stdin = process.stdin;
var stdout = process.stdout;

process.on('exit', function () {
console.error('chunks1: ' + JSON.stringify(chunks1));
console.error('chunks2: ' + JSON.stringify(chunks2));
});
process.stdout.on('error', process.exit);


// stdin.pipe(stream1).pipe(stream2).pipe(stdout);

// $ (printf "abc\nd"; sleep 1; printf "ef\nghi\n") | node streams-combine.js
// Outputs:
// 1 abc
// 2 def
// 3 ghi
// chunks1: ["abc\nd","ef\nghi\n"]
// chunks2: ["abc","def","ghi"]

// Best working solution I could find
var stream3 = function(src) {
return src.pipe(stream1).pipe(stream2);
};
stream3(stdin).pipe(stdout);

// $ (printf "abc\nd"; sleep 1; printf "ef\nghi\n") | node streams-combine.js
// Outputs:
// 1 abc
// 2 def
// 3 ghi
// chunks1: ["abc\nd","ef\nghi\n"]
// chunks2: ["abc","def","ghi"]

这有可能吗?如果不清楚我想要做什么,请告诉我。

谢谢!

最佳答案

您可以观察要通过管道传输到您的流的内容,然后将其unpipe 并将其通过管道传输到您感兴趣的流:

var PassThrough = require('stream').PassThrough;

var stream3 = new PassThrough();

// When a source stream is piped to us, undo that pipe, and save
// off the source stream piped into our internally managed streams.
stream3.on('pipe', function(source) {
source.unpipe(this);
this.transformStream = source.pipe(stream1).pipe(stream2);
});

// When we're piped to another stream, instead pipe our internal
// transform stream to that destination.
stream3.pipe = function(destination, options) {
return this.transformStream.pipe(destination, options);
};

stdin.pipe(stream3).pipe(stdout);

您可以将此功能提取到您自己的可构造流类中:

var util = require('util');
var PassThrough = require('stream').PassThrough;

var StreamCombiner = function() {
this.streams = Array.prototype.slice.apply(arguments);

this.on('pipe', function(source) {
source.unpipe(this);
for(i in this.streams) {
source = source.pipe(this.streams[i]);
}
this.transformStream = source;
});
};

util.inherits(StreamCombiner, PassThrough);

StreamCombiner.prototype.pipe = function(dest, options) {
return this.transformStream.pipe(dest, options);
};

var stream3 = new StreamCombiner(stream1, stream2);
stdin.pipe(stream3).pipe(stdout);

关于node.js - 从两个管道流创建 Node.js 流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17471659/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com