Buffer 
This is a chunk of memory where data is stored temporarily. This non-resizable memory is designed to handle raw binary data, and the integers in it are limited to values from 0 to 255 (2^8 1), with each integer representing one byte.

Streams 
Whenever you talk about reading data from a source and writing it to a destination, you’re referring to streams ( Unix pipes ).  A stream can be likened to an EventEmitter . There are four types of streams, and they are as follows: 
Readable: Allows you to read data from a source. 
Writable: Allows you to write data to a destination. 
Duplex: Allows you to read data from a source and write data to a destination. 
Transform: Allows you to modify or transform data while data is being read or written. 

Reading Data from Streams 
A stream is said to be readable if it permits data to be read from a source, irrespective of what the source is, be it another stream, a file in a filesystem, a buffer in memory, and so on. Various data events can be emitted at various points in a stream. Thus, streams can also be referred to as instances of EventEmitters.

Listening to a data event and attaching a callback are the best ways to read data from a stream. A readable stream emits a data event, and your callback executes when data is available

Let’s observe how a stream is read, a data event is emitted, and a callback is executed using the filesystem module with a readable and writable file. See the following code:      

const fs = require('fs');
const file = fs.createReadStream('readTextFile.txt');

file.on('data', function(data) {
console.log('Data '+ data);
});
file.on('end', function () {
console.log('Hey!, Am Done reading Data’);
}); 
const file = fs.createReadStream('readTextFile.txt');     file.on('data', function(data) {
console.log('Data '+ data);
});
file.on('end', function () {
console.log('Hey!, Am Done reading Data’);
}); 

First, we created a file named readTextFile.txt . Then, a readable stream is created using the fs.createReadStream(‘filename’) function. It is good to know that the stream is in a static state initially, and gets to a flowing state as soon as you listen to a data event and attach a callback. Streams emit an end event when there is no more data to read. 
More API info:  https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options

Writing to Streams
A stream is said to be writable if it permits data to be written to a destination, irrespective of what the destination is. It could be another stream, a file in a filesystem, a buffer in memory, and so on. Similar to readable streams, various events that are emitted at various points in writeable streams can also be referred to as instances of EventEmitter .

The write() function is available on the stream instance. It makes writing data to a stream possible. Take a look at the following snippet: 

const fs = require('fs');
const readableStream = fs.createReadStream('readTextFile.txt');
const writableStream = fs.createWriteStream('writeTextFile.txt');
readableStream. on('data', function (data) {
console.log('Hey!, I am about to write what has been read
from the file readTextFile.txt');
if (writableStream.write(data) === true){
console.log('Hey!, I am done writing. Open the file
writeTextFile.txt to see what has been written’);
}
else console.log('Writing is not successful');
});

First, we load the filesystem using the require directive. Then, we create two files: readTextFile.txt and writeTextFile.txt . We then write some text string into the readTextFile.txt file and leave writeTextFile.txt blank. Using the filesystem createReadStream() function with the file path or directory as an argument, we create a readable stream. Thereafter, a writeable stream is created using the filesystem createWriteStream() function with the file path or directory as an argument.

readableStream.on(‘data’, callback) listens to a data event and attaches a callback, whereas writableStream.write(data) writes data to a writable stream. Once this snippet is run, you will realize that the text string read from readTextFile.txt has been written into the writeTextFile.txt file.

More API info:
https://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options

Duplex  Recall from the short description in the previous section that a duplex is a type of stream that allows you to read data from a source and write data to a destination. Examples of duplex streams are as follows: crypto streams, TCP socket streams, zlib streams

Transform  This is another stream method that lets you modify or transform data while data is being read or written. In essence, transform streams are duplex streams with the aforementioned functionality. Examples of transform streams are as follows: crypto streams, zlib streams

Filesystems  Node has a module name File System (fs) that works with the file systems on a computer. This module, fs , performs several methods that can be implemented both synchronously and asynchronously, but there is there is no guaranteed ordering when using them. Reading, creating, updating, deleting, and renaming are some of the operations that can be performed on any text file that’s saved in a directory.

Reading Files After the required directive has been invoked for the fs module, assuming that we have a string of text contained in the text file, the file can be read by calling the readFile() function, as shown here: 
  var fs = require(‘fs’);     fs.readFile(‘readFileName.txt’, function(err, data) {         if (err) throw err;         console.log(‘Read!’);      }); 
Creating Files The methods that are highlighted here are made available by the fs module for creating new files: fs.appendFile() : This method appends a given content to a file. The file will be created in this case, even if it does not exist. This function can also be used to update a file. Its implementation is as follows: 
    var text = ‘ Hey John, Welcome to Packt class.’;    var fs = require(‘fs’);     fs.appendFile(‘newTextFile.txt’, ‘text’ ‘, function (err) {           if (err) throw err;           console.log(‘Saved!’);    }); 
Once the preceding code is run, you will see the designated string written into the file. 
fs.open(): When this method is called, a given file is opened for writing, and if the file doesn’t exist, an empty file will be created. The implementation is as follows: 
    var fs = require(‘fs’);      fs.open(‘TextFile.txt’, ‘w’, function (err, file) {           if (err) throw err; // let’s assume the file doesn’t exist           console.log(‘An empty file created’);    }); 
This method takes a second argument, w , which is referred to as a flag for “writing.”
fs.writeFile(): When this method is called on a given file and content exists in it, the existing content is replaced by new content. In a situation where the file doesn’t exist, a new file containing the given content will be created. This function can also be used to update the file, and the implementation is as follows: 
    var fs = require(‘fs’);     fs.writeFile(‘textFile.txt’, ‘Hello content!’, function (err) {         if(err)throw err;         console.log(‘Saved!’);   }); 
Deleting Files 
fs.unlink(): When this method is called on a given file in the filesystem, the file is deleted. The implementation is as follows: 
    var fs = require(‘fs’);      fs.unlink(‘textFile.txt’, function (err) {           if (err) throw err;           console.log(‘File deleted!’);   }); 
Renaming Files
fs.rename(): This method takes in three arguments: the old name of the file, the new name of the file, and a callback. When this method is called on a given file in the filesystem, the file is renamed. The implementation is as follows: 
    var fs = require(‘fs’);     fs.rename(‘textFile.txt’, ‘renamedtextFile.txt’, function (err) {        if (err) throw err;           console.log(‘File Renamed!’);   }); 
Some Other Methods in the Filesystems Module 
access(): This method is used to check whether a user has access to the file or directory. 
close(): This method is used to close a file. 
exists(): Though this method is deprecated, it’s called on a file to check whether a file or folder exists. 
fstat(): When this method is called on a file, it returns the status of that file. 
link(): This method is used to create an additional name for a file. The name could either be the old or a new one. 
mkdir(): This method is used make a new directory. 
readdir(): This method is used to read the contents of a directory. 
rmdir(): This method is used to remove a directory. stat() : This method is used to return the status of a file.