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

时间:2022-09-02 02:31:15

In RingoJS there's a function called read which allows you to read an entire stream until the end is reached. This is useful when you're making a command line application. For example you may write a tac program as follows:

在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

This allows you to fire up a shell and run the tac command. Then you type in as many lines as you wish to and after you're done you can press Ctrl+D (or Ctrl+Z on Windows) to signal the end of transmission.

这允许您启动shell并运行tac命令。然后输入你想要的行数,完成后你可以按Ctrl+D(或者在Windows上按Ctrl+Z)来通知传输结束。

I want to do the same thing in node.js but I can't find any function which would do so. I thought of using the readSync function from the fs library to simulate as follows, but to no avail:

我想在结点上做同样的事情。但是我找不到任何函数可以这样做。我想用fs库中的readSync函数来模拟如下,但是没有效果:

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

The file descriptor for stdin (the first argument) is 0. So it should read the data from the keyboard. Instead it gives me the following error:

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)

How would you synchronously collect all the data in an input text stream and return it as a string in node.js? A code example would be very helpful.

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

4 个解决方案

#1


12  

The key is to use these two Stream events:

关键是使用这两个流事件:

Event: 'data'
Event: 'end'

For stream.on('data', ...) you should collect your data data into either a Buffer (if it is binary) or into a string.

流。在('data',…)上,您应该将数据数据收集到缓冲区(如果是二进制)或字符串中。

For on('end', ...) you should call a callback with you completed buffer, or if you can inline it and use return using a Promises library.

对于on('end',…),您应该使用已完成的缓冲区调用回调,或者如果可以内联它并使用promise库使用return的话。

#2


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

作为节点。js是事件和面向流的,没有API可以等待stdin和缓冲区结果的结束,但是很容易手工完成。

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(''));
});

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)

在大多数情况下,最好不要缓存数据并在数据到达时处理它们(使用xml或zlib等已有的流解析器链或您自己的FSM解析器)

#3


5  

There is a module for that particular task, called concat-stream.

有一个特定任务的模块,叫做concatt -stream。

#4


4  

Let me illustrate StreetStrider's answer.

让我来解释一下街头漫游者的回答。

Here is how to do it with concat-stream

下面是如何使用concatstream

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);
});

Please note that process.stdin is a stream.

请注意过程。标准输入流。

#1


12  

The key is to use these two Stream events:

关键是使用这两个流事件:

Event: 'data'
Event: 'end'

For stream.on('data', ...) you should collect your data data into either a Buffer (if it is binary) or into a string.

流。在('data',…)上,您应该将数据数据收集到缓冲区(如果是二进制)或字符串中。

For on('end', ...) you should call a callback with you completed buffer, or if you can inline it and use return using a Promises library.

对于on('end',…),您应该使用已完成的缓冲区调用回调,或者如果可以内联它并使用promise库使用return的话。

#2


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

作为节点。js是事件和面向流的,没有API可以等待stdin和缓冲区结果的结束,但是很容易手工完成。

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(''));
});

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)

在大多数情况下,最好不要缓存数据并在数据到达时处理它们(使用xml或zlib等已有的流解析器链或您自己的FSM解析器)

#3


5  

There is a module for that particular task, called concat-stream.

有一个特定任务的模块,叫做concatt -stream。

#4


4  

Let me illustrate StreetStrider's answer.

让我来解释一下街头漫游者的回答。

Here is how to do it with concat-stream

下面是如何使用concatstream

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);
});

Please note that process.stdin is a stream.

请注意过程。标准输入流。