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

javascript, node.js, ringojs, stdin, stream

Solution

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.

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.

Problem

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: ``` #!/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. 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(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: ``` 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.

Original source

Related problems