如何读取node.js中的整个文本stream?

在RingoJS中有一个叫做read的函数 ,它允许你读完整个stream,直到到达结尾。 在制作命令行应用程序时,这非常有用。 例如,你可以写一个tac 程序如下:

 #!/usr/bin/env ringo var string = system.stdin.read(); // read the entire input stream var lines = string.split("\n"); // split the lines lines.reverse(); // reverse the lines var reversed = lines.join("\n"); // join the reversed lines system.stdout.write(reversed); // write the reversed lines 

这可以让你启动一个shell并运行tac命令。 然后input你想要的行数,完成后你可以按下Ctrl + D (或Windows上的Ctrl + Z )来表示传输结束 。

我想在node.js做同样的事情,但我找不到任何function。 我想从fs库中使用readSync 函数来模拟如下,但无济于事:

 fs.readSync(0, buffer, 0, buffer.length, null); 

stdin的文件描述符 (第一个参数)是0 。 所以它应该从键盘读取数据。 相反,它给了我以下错误:

 Error: ESPIPE, invalid seek at Object.fs.readSync (fs.js:381:19) at repl:1:4 at REPLServer.self.eval (repl.js:109:21) at rli.on.self.bufferedCmd (repl.js:258:20) at REPLServer.self.eval (repl.js:116:5) at Interface.<anonymous> (repl.js:248:12) at Interface.EventEmitter.emit (events.js:96:17) at Interface._onLine (readline.js:200:10) at Interface._line (readline.js:518:8) at Interface._ttyWrite (readline.js:736:14) 

你将如何同步收集input文本stream中的所有数据,并将其作为string在node.js中返回? 一个代码示例会非常有帮助。

关键是要使用这两个stream事件:

 Event: 'data' Event: 'end' 

对于stream.on('data', ...)您应该将您的数据数据收集到Buffer(如果是二进制)或string中。

对于on('end', ...)你应该调用你完成的缓冲区的callback,或者如果你可以内联它并使用Promise库来使用返回。

由于node.js是面向事件和stream的,所以在stdin和缓冲区结果结束之前没有可以等待的API,但是很容易手动

 var content = ''; process.stdin.resume(); process.stdin.on('data', function(buf) { content += buf.toString(); }); process.stdin.on('end', function() { // your code here console.log(content.split('').reverse().join('')); }); 

在大多数情况下,最好不要缓冲数据,并在到达时处理传入的块(使用可用的streamparsing器(如xml或zlib或您自己的FSM分析器)

这个特定任务有一个模块,称为concat-stream

让我来说明一下StreetStrider的回答。

这是如何用concat-stream来完成的

 var concat = require('concat-stream'); yourStream.pipe(concat(function(buf){ // buf is a Node Buffer instance which contains the entire data in stream // if your stream sends textual data, use buf.toString() to get entire stream as string var streamContent = buf.toString(); doSomething(streamContent); })); // error handling is still on stream yourStream.on('error',function(err){ console.error(err); }); 

请注意process.stdin是一个stream。