如何读取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。