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

Aad*_*hah 22 javascript stdin stream node.js ringojs

在RingoJS中有一个叫做的函数read,它允许你读取整个流,直到到达终点.这在您创建命令行应用程序时很有用.例如,您可以编写如下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
Run Code Online (Sandbox Code Playgroud)

这允许您启动shell并运行tac命令.然后根据需要输入任意数量的行,完成后可以按Ctrl+ D(或Windows上的Ctrl+ Z)表示传输结束.

我想在node.js中做同样的事情,但我找不到任何会这样做的函数.我想用的readSync 功能,fs图书馆到模拟如下,但无济于事:

fs.readSync(0, buffer, 0, buffer.length, null);
Run Code Online (Sandbox Code Playgroud)

对标准输入文件描述符(第一个参数)是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)
Run Code Online (Sandbox Code Playgroud)

您将如何同步收集输入文本流中的所有数据并将其作为node.js中的字符串返回?代码示例非常有用.

And*_*rov 28

As node.js is event and stream oriented there is no API to wait until end of stdin and buffer result, but it's easy to do manually

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(''));
});
Run Code Online (Sandbox Code Playgroud)

In most cases it's better not to buffer data and process incoming chunks as they arrive (using chain of already available stream parsers like xml or zlib or your own FSM parser)

  • 您可以执行`process.stdin.setEncoding('utf-8');`在恢复之后,回调中的`bug`已经是字符串. (5认同)
  • 类似,但使用`Buffer.concat()`:http://stackoverflow.com/questions/10686617/how-can-i-accumulate-a-raw-stream-in-node-js#23304138 (3认同)

Nat*_*han 14

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

Event: 'data'
Event: 'end'
Run Code Online (Sandbox Code Playgroud)

因为stream.on('data', ...)您应该将数据数据收集到Buffer(如果是二进制)或字符串中.

因为on('end', ...)您应该使用完成的缓冲区调用回调,或者如果您可以内联它并使用Promises库返回.


Str*_*der 5

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


Ali*_* Ok 5

让我来说明 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);
});
Run Code Online (Sandbox Code Playgroud)

请注意,这process.stdin是一个流。