Read all text from stdin to a string

2020-02-10 01:15发布

问题:

I'm writing a program in Node.js that (in some situations) wants to act as a simple filter: read everything from stdin (up to end of file), do some processing, write the result to stdout.

How do you do the 'read everything from stdin' part? The closest solutions I've found so far, seem to work either for one line at a time from the console, or else only work when stdin is a file not a pipe.

回答1:

My boiler-plate for this one is a lot like the solution described in a comment above -- offering it at the top level because it's very much the simplest way to do this and it shouldn't be only in a comment.

var fs = require('fs');
var data = fs.readFileSync(0, 'utf-8');
// Data now points to a buffer containing the file's contents


回答2:

If you're on linux, there is no need for a 3rd party package for this. of course, consider your performance needs, but these two lines will work:

const fs = require("fs");
const data = fs.readFileSync("/dev/stdin", "utf-8");

Jan points out in the comments below that a more portable solution would be to use 0, as this is the POSIX standard. So, you may simple use:

const fs = require("fs");
const data = fs.readFileSync(0, "utf-8");

data is now a string with your data from stdin, interpreted as utf 8



回答3:

get-stdin will do the trick.


A few notes reading between the lines in your question.

Since you tagged the question "synchronous" I'll just note that stdin is async-only in node.js. The above library is the simplest it gets. It will handle the entire input as either a string or a buffer.

If possible, writing your program in the streaming style is best, but some use cases are feasible for streaming (i.e. word count) and some are not (i.e. reverse the input).

Also the "one line at a time from the console" is an artifact of the terminal buffering your keystrokes. If you want some "I'm sorry I asked" level detail check out the amazing the TTY Demystified.



回答4:

I use the following in Node 11+

async function read(stream) {
    let buffer = Buffer.alloc(0);
    for await (const chunk of stream) {
        buffer = Buffer.concat([buffer, chunk]);
    }
    return buffer.toString('utf8');
}

Usage:

const input = await read(process.stdin);