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
How to read an entire text stream in node.js?
提问by Aadit M Shah
In RingoJS there's a functioncalled 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
programas 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+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 readSync
functionfrom the fs
library 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
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.
请注意,这process.stdin
是一个流。