在RingoJS中有一个名为read
的函数,它允许你读取整个流,直到到达结尾。这在你制作命令行应用程序时很有用。例如,你可以写一个tac
program如下:
#!/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
命令。然后你输入你想要的行,完成后你可以按Ctrl+D(或Windows上的Ctrl+Z)来发送信号end of transmission。
我想在node.js中做同样的事情,但我找不到任何函数可以这样做。我想使用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)
如何在node.js中同步收集输入文本流中的所有数据并将其作为字符串返回?一个代码示例会很有帮助。
7条答案
按热度按时间laximzn51#
由于node.js是面向事件和流的,因此没有API等待stdin和buffer结果结束,但很容易手动完成
在大多数情况下,最好不要缓冲数据并在数据块到达时处理它们(使用已经可用的流解析器链,如xml或zlib或您自己的FSM解析器)
kiz8lqtg2#
关键是使用这两个Stream事件:
对于
stream.on('data', ...)
,您应该将数据收集到Buffer(如果是二进制)或字符串中。对于
on('end', ...)
,您应该使用已完成的buffer调用回调,或者如果您可以内联它并使用Promises库使用return。xytpbqjk3#
让我来举例说明StreetStrider的答案。
以下是如何使用concat-stream执行此操作
请注意,
process.stdin
是一个流。yjghlzjz4#
有一个用于该特定任务的模块,名为**concat-stream**。
cig3rfwq5#
如果你在
async
环境中并且有最新版本的Node.js,这里有一个快速的建议:ccgok5k56#
在Windows上,我在这里发布的其他解决方案中遇到了一些问题-当没有输入时,程序将无限期地运行。
这是现代NodeJS的TypeScript实现,使用异步生成器和
for await
-比使用旧的基于回调的API更简单,更健壮,这在Windows上工作:示例:
(如果您想处理Promise拒绝,并在没有输入时显示一个更友好的错误消息,请考虑添加
try/catch
。)mum43rcc7#
这是一个老问题,但值得一提的是,Node.js有一些新的流助手,其中之一是toArray:
**请注意:**此API目前标记为实验性,因此可能更适合测试/非生产代码。