在node.js中过滤Stream对象

在我看来,处理Node.js中某些types数据的一种优雅的方式是链处理对象,比如UNIXpipe道。

例如,grep:

function Grep(pattern) { ... } util.inherits(Grep, stream.Stream); Grep.prototype.???? = ??????? // What goes here? grep = new Grep(/foo/); process.stdin.pipe(grep); myStream.pipe(process.stdout); 

然而,我不完全清楚如何覆盖各种stream方法才能使其工作。

我怎样才能创build一个Stream对象,只需从其input复制到其输出? 据推测,更复杂的过滤stream变得微不足道。

更新:感觉好像下面的工作(用CoffeeScript表示,所以我不用JS语法填充这个框):

 class Forwarder extends stream.Stream write: (chunk, encoding) -> @emit 'data', chunk end: (chunk, encoding) => if chunk? @emit 'data', chunk @emit 'end' fwd = new Forwarder() fwd.pipe(process.stdout); process.stdin.pipe(fwd); process.stdin.resume(); 

然而,捕捉这个脚本的东西不会输出任何东西。 在脚本中显式调用“fwd.write()”会导致stdout输出。

你非常亲密

因为您使用的是非常低级别的stream类,所以您需要设置stream可写属性以使其成为可写stream。 如果您正在阅读stream,则需要设置可读属性。 结束事件也没有任何参数。

 class Forwarder extends stream.Stream constructor: -> @writable = true write: (chunk, encoding) -> @emit 'data', chunk end: -> @emit 'end' fwd = new Forwarder() fwd.pipe(process.stdout); process.stdin.pipe(fwd); process.stdin.resume(); 

更新

上面的答案适用于Node <= 0.8中的V1stream。 如果使用> 0.8,Node添加了更多特定的类,这些类被devise为扩展,所以你可以使用更多的类似的东西:

 class Forwarder extends stream.Transform _transform: (chunk, encoding, callback) -> this.push(chunk); callback(); 

处理chunk和推动你真正想要的作品。

尽pipe存在的答案很好,但仍然需要代表那些寻找答案的人进行挖掘。

以下代码使用Node 0.10streamAPI完成了OP给出的示例。

 var stream = require('stream') var util = require('util') function Grep(pattern) { stream.Transform.call(this) this.pattern = pattern } util.inherits(Grep, stream.Transform) Grep.prototype._transform = function(chunk, encoding, callback) { var string = chunk.toString() if (string.match(this.pattern)) { this.push(chunk) } callback() } var grep = new Grep(/foo/) process.stdin.pipe(grep) grep.pipe(process.stdout)