Reading streams with promises in Node.js
The fs.promises API doesn't provide a way to read streams in Node.js. Here's how to do it.
If you’ve tried to use the Node.js fs.promises
API, you might have noticed that there doesn’t appear to be a cross-platform way of using fs.readFile()
to read from process.stdin
(such as process.stdin
). Using the old, callback-based API, you could pass in a numeric file descriptor, such as:
import fs from "fs";
const text = fs.readFileSync(0, "utf8");
However, when using the fs.promises
version of readFile()
, you can no longer use numeric file descriptors (an error is thrown). While you can use the string "/dev/stdin"
on Linux machines, but that doesn’t work on Windows machines.
The easiest way to read stream using promises is to write your own function do so. Here’s what mine looks like:
function readStream(stream, encoding = "utf8") {
stream.setEncoding(encoding);
return new Promise((resolve, reject) => {
let data = "";
stream.on("data", chunk => data += chunk);
stream.on("end", () => resolve(data));
stream.on("error", error => reject(error));
});
}
const text = await readStream(process.stdin);
The key is to listen to three events:
data
for the pieces of data being readend
to resolve the promise with the accumulated dataerror
to reject the promise if there’s an error
Because readStream()
returns a promise, you can use await
to call it, making it fit in with the rest of the fs.promises
API.