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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13410960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 18:41:09  来源:igfitidea点击:

How to read an entire text stream in node.js?

javascriptnode.jsstreamstdinringojs

提问by Aadit M Shah

In RingoJS there's a functioncalled readwhich 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 tacprogramas 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 taccommand. Then you type in as many lines as you wish to and after you're done you can press Ctrl+D(or Ctrl+Zon 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 readSyncfunctionfrom the fslibrary to simulate as follows, but to no avail:

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

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:

对标准输入文件描述符(第一个参数)是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 中将其作为字符串返回?代码示例将非常有帮助。

采纳答案by Nathan

The key is to use these two Stream events:

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

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.

因为stream.on('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', ...)您应该使用已完成的缓冲区调用回调,或者如果您可以内联它并使用 Promises 库使用 return。

回答by Andrey Sidorov

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

由于 node.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 解析器)

回答by Strider

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

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

回答by Ali Ok

Let me illustrate StreetStrider's answer.

让我来说明 StreetStrider 的回答。

Here is how to do it with concat-stream

这是使用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);
});

Please note that process.stdinis a stream.

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