Streams

We have already seen how to read stdin (input from the terminal) as follows:

console.log(process.stdin);

A program can take input from many different sources of streaming data. Readline module provides an interface to read data from any Readable stream including process.stdin. See https://nodejs.org/api/readline.html. Following is a simple example, I picked up from Readline documentation.

const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question('What do you think of Node.js? ', (answer) => {
  console.log(`Thank you for your valuable feedback: ${answer}`);
  rl.close();
});

The first line requires the module. It is a core module so you don't need to install anything using npm. The next block defines the input and output source for the interface. We specified stdin as data source and will output to stdout. The last block prompts a question and then prints the response in the console.

Data can come from or go to many different sources such as text files, JSON, and XML. Streams are objects that allow you to read from or write to a data source.

EventEmitters for streams are:

  • Data: when data is available for reading
  • End : when there is no more data to read
  • Error: where there is an error read from or writing to a stream
  • Finish: when you are done using the stream

The following code show how to read from a file using these EventEmitters:

var fs = require("fs");
var content = '';

// open file and create stream for reading
var rs = fs.createReadStream('in.txt');

// read from the file
rs.on('data', function(txt) {
  console.log(txt);    
  content += txt;
  console.log(content);
});

// done reading
rs.on('end', function(){
  console.log('done reading');
})

// print any errors          
rs.on('error', function(err){
  console.log(err.stack);
})   

Save this file as readfromfile.js. Create a text file, in.txt with the following contents and save in the same directory as readfromfile.js.

one
two
three

The output:

<Buffer 6f 6e 65 0a 74 77 6f 0a 74 68 72 65 65>
one
two
three
done reading

Note that the first line output is the print out of the stream, so it is a buffer. When we assign the buffer to a text variable, it is converted to string data.

Code to append to a file, simply use the following code

var fs = require("fs");
var as = fs.appendFile('in.txt','four');

It appends the word four to the file. To write to a new file,

var fs = require("fs");
var content = 'Four';

// write stream to file
var ws = fs.createWriteStream('out.txt');
ws.write(content);
ws.end();

ws.on('error', function(err){
  console.log(err.stack);
});

This code writes the word Four in out.txt file. If the file does not exist, it will create it. If it exists, it will be overwritten. The following code pipes contents of an input file into an output file.

var fs = require("fs");

// create read and write streams and pipe them
var rs = fs.createReadStream('in.txt');
var ws = fs.createWriteStream('out.txt');
rs.pipe(ws);