在我看来,在Node.js中处理某些类型数据的优雅方法是链接处理对象,如UNIX管道。
例如,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方法以使其工作。
如何创建简单地从输入复制到输出的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输出。
答案 0 :(得分:8)
你非常亲密。
因为您使用的是非常低级的流类,所以需要设置流可写属性以使其成为可写流。如果您正在从流中读取,则需要设置可读属性。此结束事件也没有任何参数。
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中的V1流。如果您使用> 0.8,Node添加了更多旨在扩展的特定类,因此你可以使用更像这样的东西:
class Forwarder extends stream.Transform
_transform: (chunk, encoding, callback) ->
this.push(chunk);
callback();
处理chunk
并推送您真正想要的部分。
答案 1 :(得分:3)
虽然存在的答案很好,但仍需要代表那些寻找答案的人进行一些挖掘。
以下代码使用Node 0.10流API完成了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)