Node.js File System

Introduction to File System in Node.js

FS, abbreviated as File System, is a Node.js Build-in Module, which provides an Application Programming Interface (API) to interact with the File System, and to perform some I/O operations. For example, to create a file, read a file, delete a file, update a file, and many more.

Importing fs Module

Since fs Module comes along with the Node.js Platform, therefore, to import the File System module, we need to use therequire() method. The syntax is given as:

const fs = require(‘fs’)

But, before we get into the coding part, there are some fundamental concepts regarding the File System that an individual must know. Let’s discuss these fundamentals:

Difference between Synchronous and Asynchronous

The execution of code in a sequence is mentioned as Synchronous (or Sync) execution. The program runs line by line in Sync programming, which means one line is executed at a time. Whenever a function is called, the program's execution waits until that function returns before moving on to the next line of code. Synchronous execution uses Blocking methods.

On the other hand, Asynchronous (or Async) execution doesn't work in the sequence as it appears in code. Moreover, the program doesn't wait for the task to be completed before moving on to the next task in Async programming. Asynchronous execution uses Non-blocking methods.

Every fs method includes both synchronous and asynchronous form. However, we can add Sync at end, to make the function synchronous, which means that an asynchronous fs.writeFile() becomes fs.writeFileSync().

Basic Operations of File System

File System uses basic CRUD operations, which includes:

  • Create Files
  • Read Files
  • Update Files
  • Delete Files
  • Rename Files

Creating a File using fs module

There are some methods used in the File System module for creating new files:

  • fs.writeFile() and fs.writeFileSync()
  • fs.appendFile() and fs.appendFileSync()
  • fs.open() and fs.openSync()

Let’s discuss the above methods:

  • The fs.writeFile() and fs.writeFileSync() methods are used to write content to a File. If a file with similar name already exists, it overwrites the existing data or creates a new file and writes the content into that file.

Let's see the following example:

File: create.js

const fs = require('fs')
console.log("Creating New Files!");
// Asynchronous version to create a new file
fs.writeFile('input.txt', "Welcome to TUTORIALANDEXAMPLE.COM Tutorials", function(err) {
   if (err) {
      return console.error(err);
   }
   console.log("input.txt has been created successfully!!");
})
// Synchronous version to create a new file
fs.writeFileSync('read.txt', "Easy Learning with TUTORIALANDEXAMPLE.COM")
console.log("read.txt has been created successfully!!")

To see the output, let’s execute the above program:

$ node create.js

By executing the above code, we will get the below output:

Creating New Files!
read.txt has been created successfully!!
input.txt has been created successfully!!
Node.js File System
  • Apart from the fs.writeFile() method, the fs.appendFile() method is also used to create new files. The fs.appendFile() and fs.appendFileSync() methods are mostly used to append or add  the specified content to a file. However, if the file does not exist, the new file will be created.

Let’s understand the above methods with the help of an example:

File: append.js

const fs = require('fs');
console.log("Creating New Files!");
// Asynchronous Version to create a file using append
fs.appendFile('newfile.txt', "This is my New File.", function (err) {
  if (err) throw err;
  console.log("newfile.txt has been created successfully!!")
}); 
// Synchronous Version to create a file using append
fs.appendFileSync('secondfile.txt', "This is my Second File.")
console.log("secondfile.txt has been created successfully!!")

To see the output, let’s run the above program:

$ node append.js

We’ll get the output as shown below:

Creating New Files!
secondfile.txt has been created successfully!!
newfile.txt has been created successfully!!
Node.js File System

As we can see that the fs.appendFile() and fs.appendFileSync() methods have created two different files, if no existing files are found in the respective directory. But the primary function of using this method implies that the specified context should be added to the existing file. So, taking this into command, let’s see one more example:

File: append.js

const fs = require('fs');
console.log("Updating New Files!");
// Asynchronous Version of append to add content to the existing file
fs.appendFile('newfile.txt', " Since my file is already exists, therefore it will simply add this content to the file.", function (err) {
  if (err) throw err;
  console.log("newfile.txt has been updated successfully!!")
}); 

To see the output, let’s execute the above script again:

$ node append.js

We’ll see the output as shown below:

Updating New Files!
newfile.txt has been updated successfully!!
Node.js File System
  • The fs.open() method can be used to create and write the content in a document. However, the fs.open() and fs.openSync() methods are used to open the specific files and document. Moreover, fs.open() method also allows the users to read, write and append something in the document, but uses different flags to serve different purposes.

Let’s see the following example to understand the use of fs.open() method.

File: open.js

const fs = require('fs');
console.log("Opening the files!!");
// Asynchronous Version to open / create a file
fs.open('new-file.txt', 'w', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("new-file.txt opened successfully!");
});
// Synchronous Version to open / create a file
fs.openSync('newdoc.txt', 'w');
console.log("newdoc.txt opened successfully!");
To execute the above script, type the following command on node.js command-line:
$ node open.js

The Output for the above program is shown below:

Opening the files!!
newdoc.txt opened successfully!
new-file.txt opened successfully!

From the above output, we can conclude that if the file doesn’t exist with the designated name and path described in the fs.open() method, it will create the document and write in it. Moreover, it is a point to be noted that the fs.open() method returns Integer representation for the file descriptor. Here’s an example for the same:

File: open.js

const fs = require('fs');
console.log("Opening the files!!");
// Asynchronous Version to Open a File 
fs.open('newfile.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File is Opened successfully!");
   console.log("Content of the File: " + fd.toString());
});
Now, we can execute the open.js to see the output.
$ node open.js
The Output of the above code is given as below:
Opening the files!!
File is Opened successfully!

Content of the File: 3

There are the following flags available for the File System module and can be used whenever the flag option takes the string:

S.No.FlagDescription
1rThis flag is used to open the document for reading. This is by default flag, if no flag is defined within the method. However, if the file doesn’t exist, an exception would occur.
2r+This flag is used to open the file to read and write the content. It would also give an exception with the document if file doesn’t exist.
3rsThis flag is the synchronous mode to open the file for reading.
4rs+This flag is also the synchronous mode to open the file for reading and writing the content.
5wThis flag is used to open the file to write the content in it. However, if the file doesn’t exist, it will create a new file, or if the document exists, it will truncate it.
6wxThis flag is an alias of ‘w’; however, it fails if the path exists.
7w+This flag is used to open the file to write and read the content. It functions same as ‘w’.
8wx+This flag is an alias for ‘wx+’; however, it also fails if the path exists.
9aThis flag is used to open the file to append. It also creates the file if the file doesn’t exist.
10axThis flag is similar to ‘a’, but it fails if the path exists.
11a+The flag is used to open the file, and to append and read the file. It functions the same as ‘a’.
12ax+This flag works similar to ‘a+’, but it fails if the path exists.

Reading a File using fs module

There is a method used for reading files on our system with the help of the fs module. This method is known as the fs.readFile() method. We can also use fs.readFileSync() for the Synchronous reading of the file.

Here’s an example to demonstrate the use of fs.readFile() and fs.readFileSync():

File: read.js

const fs = require('fs');
console.log("Opening File to Read!!")
console.log("Reading the file!")
// Asynchronous Version of reading a file
fs.readFile('./newfile.txt',function(err, fd){
        if (err) throw err;
        console.log("Asynchronous Read: " + fd.toString());
});
// Synchronous Version of reading a file
var data = fs.readFileSync('./newfile.txt');
console.log("Synchronous Read: " + data.toString());

In the above example, we have used “./newfile.txt”, located in the same path as of script file. Now, let’s execute the above program to see the result:

$ node read.js

The Output of the above code will look like as below:

Opening File to Read!!
Reading the file!
Synchronous Read: Welcome to TUTORIALANDEXAMPLE.COM Tutorials.
Learning is so easy with TUTORIALANDEXAMPLE.COM Tutorials.
Asynchronous Read: Welcome to TUTORIALANDEXAMPLE.COM Tutorials.
Learning is so easy with TUTORIALANDEXAMPLE.COM Tutorials.

Updating a file using fs module

We can easily update our files and documents using the following methods of the File System module:

  • fs.appendFile()
  • fs.writeFile()

As we have already learned about the functioning of fs.appendFile() and its synchronous version in the above section, it can also be used to update the file's content. It is because the append method allows the user to add the content to the file.

Similarly, fs.writeFile() is used to create a new file and write in it. However, the secondary use of this method is overwriting the file, which allows the user to replace the specified content and the file.

Deleting a file using the fs module

In Node.js, the File System module has already defined the methods that allow the users to delete or truncate a file. These methods are:

  • fs.unlink()
  • fs.ftruncate()

The fs.unlink() and its synchronous version, fs.unlinkSync(), are used to remove a file or a symbolic link. Let's see an example to understand the use of this method:

File: delete.js

const fs = require('fs');
console.log("Deleting the Files!");
// Asynchronous version to delete a file
fs.unlink('./input.txt', function(err){
    if (err) {
        return console.error(err);
    }
    console.log("input.txt has been removed successfully!!");
});
// Synchronous version to delete a file
fs.unlinkSync('./input-1.txt');
console.log("input-1.txt has been removed successfully!!");

To execute the above program, type the following command in the node.js terminal:

$ node delete.js

Here’s the Output of the same:

Deleting the Files!
input-1.txt has been removed successfully!!
input.txt has been removed successfully!!

To verify our Output or to check whether our method works or not, we can type ‘dir’ on the command prompt in windows, or lson Linux terminal, to check the directory, if the file exist or not. Here’s a preview for the same.

Node.js File System

Moving onto another method, we have fs.ftruncate(). However, it doesn't help us to delete or remove any file from the directory; instead, the fs.ftruncate() is used to modify the file's size; it means, either we can increase the file size or decrease it. The fs.ftruncate() method changes the file's length at the path by len bytes. The file is truncated to a specified length, if len is shorter than the current length of the file at the path. The file length can also be padded by appending the null bytes (x00) until len is reached, if it is more significant than the file's length.

The fs.ftruncate() method is much similar to the fs.truncate() method. However, fs.truncate() doesn’t accept the file descriptor of the file to truncate, whereas, fs.ftruncate() can pass the file descriptor as the first argument.

Here’s an example demonstrating the use of fs.ftruncate() and its synchronous version, fs.ftruncateSync() methods.

File: truncate.js

const fs = require('fs');
console.log("Content of the file before truncate: ");
// Reading the content of the file before truncate
console.log(fs.readFileSync('newfile.txt', 'utf8'));
// Getting the file descriptor of the file
const fd = fs.openSync('newfile.txt', 'r+');
// Synchronous version to truncate a file
fs.ftruncateSync(fd, 36);
    console.log("Synchronous Truncating of the file: ");
    console.log(fs.readFileSync('newfile.txt', 'utf8'));
// Asynchronous version to truncate a file
fs.ftruncate(fd, 24, function(err){
    if (err) throw err;
    console.log("Asynchronous Truncating of the file: ");
    console.log(fs.readFileSync('newfile.txt', 'utf8'));
});

Let's execute the following program to see the Output:

$ node truncate.js

The Output of the above code will look like as follows:

Content of the file before truncate:
Welcome to TUTORIALANDEXAMPLE.COM Tutorials.
Learning is so easy with TUTORIALANDEXAMPLE.COM Tutorials.
Synchronous Truncating of the file:
Welcome to TUTORIALANDEXAMPLE.COM Tu
Asynchronous Truncating of the file:
Welcome to TUTORIALANDEX

As you can see, in the above output, the file has been truncated to a specified length. However, we can also use the fs.ftruncate() method to clear off all the files’s content. For this, we don't have to specify the len to truncate the file.

Let's try an example to demonstrate the purpose of the fs.ftruncate() method:

File: truncate.js

const fs = require('fs');
console.log("Content of the file before truncate: ");
// Reading the content of the file before truncate
console.log(fs.readFileSync('newfile.txt', 'utf8'));
// Getting the file descriptor of the file
const fd = fs.openSync('newfile.txt', 'r+');
// Asynchronous version to truncate a file
fs.ftruncate(fd, function(err){
    if (err) throw err;
    console.log("Content of the file after truncate: ");
    console.log(fs.readFileSync('newfile.txt', 'utf8'));
});

To see the Output of the above script file, type the following command:

$ node truncate.js

The Output should look like as follows:

Content of the file before truncate:
Welcome to TUTORIALANDEXAMPLE.COM Tutorials.
Learning is so easy with TUTORIALANDEXAMPLE.COM Tutorials.
Content of the file after truncate:

Renaming a file using fs module

In Node.js, the fs module provides us the fs.rename() method that allows the user to rename any file. We can either use fs.rename() or its Synchronous version, i.e. fs.renameSync() to rename the files. Let’s see an example to understand its use:

File: rename.js

const fs = require('fs');
console.log("Renaming the file!");
// Asynchronous version to rename the file
fs.rename('./newfile.txt', 'mytext.txt', function(err){
    if (err){
        console.error(err);
    }
    console.log("Asynchronous Rename: newfile.txt --> mytext.txt");
    console.log("Congratulations! The Files are renamed Successfully!!");
});
// Synchronous version to rename the file
fs.renameSync('newdoc.txt', 'mydoc.txt')
console.log("Synchronous Rename: newdoc.txt --> mydoc.txt");

To execute the above program and see the Output, type the following command on the terminal:

$ node rename.js

The Output should look like as below:

Renaming the file!
Synchronous Rename: newdoc.txt --> mydoc.txt
Asynchronous Rename: newfile.txt --> mytext.txt
Congratulations! The Files are renamed Successfully!!

Moreover, we can also check the directory to see the change in name to verify our Output.

Other Operations available in Node.js File System

There are many other operations available in Node.js File System Module. However, some of them only interact with the files, and some are used to interact with the directory. We will discuss all of them in this section in brief.

·        To Get File Information: fs.stat()

File System module of Node.js has the fs.stat() method that can easily access the files' information. For the Synchronous method to get the files' information, we can use fs.statSync(). The fs.stat() uses one of its arguments as stats, an instance of fs.Stats class. The stats argument will help the system to check the file type. Some of these methods are given below:

S.No.MethodDescription
1stats.isFile()This method returns true if fs.Stats instance describes a regular file.
2stats.isDirectory()This method returns true if fs.Stats instance describes a directory.
3stats.isSymbolicLink()This method returns true if fs.Stats instance describes a Symbolic Link.
4stats.isBlockDevice()This method returns true if fs.Stats instance describes a Block device.
5stats.isFIFO()This method returns true if fs.Stats instance describes a First-In-First-Out (FIFO) pipe.
6stats.isCharacterDevice()This method returns true if fs.Stats instance describes a Character Device.
7stats.isSocket()This method returns true if fs.Stats instance describes a socket.

Let’s see an example based on the fs.stat() method:

File: stats.js

const fs = require('fs');
console.log("Going to get file info!");
// Asynchronous Version to get the information of a file
fs.stat('mytext.txt', function (err, stats) {
   if (err) {
      return console.error(err);
   }
   console.log(stats);
   console.log("Got file info successfully!");
   // Check file type
   console.log("Does fs.Stats describe a File ? " + stats.isFile());
   console.log("Does fs.Stats describe a Directory ? " + stats.isDirectory());    
});

To execute the above program, type the following command on the terminal:

$ node stats.js

The Output should look like, as shown below:

Goin to get file info!
Stats {
  dev: 1689758702,
  mode: 33206,
  nlink: 1,
  uid: 0,
  gid: 0,
  rdev: 0,
  blksize: 4096,
  ino: 844424930133288,      
  size: 76,
  blocks: 0,
  atimeMs: 1603278261238.7883,
  mtimeMs: 1603278261173.634,
  ctimeMs: 1603278261173.634,
  birthtimeMs: 1602946347682.6797,
  atime: 2020-10-21T11:04:21.239Z,
  mtime: 2020-10-21T11:04:21.174Z,
  ctime: 2020-10-21T11:04:21.174Z,
  birthtime: 2020-10-17T14:52:27.683Z
}
Got file info successfully!
Does fs.Stats describe a File ? true
Does fs.Stats describe a Directory ? false

As we can observe, ‘stats’ has stored all the information regarding ‘mytext.txt’, and printed it to the user when called. Moreover, we’ve also used two fs.Stats method to check, if the chosen file is a regular file or a directory.

To close a file: fs.close()

Node.js File System modules provide the fs.close() and its Synchronous version fs.closeSync(), methods to close an opened file. Here’s an example to understand the use of this method:

File: close.js

const fs = require('fs'); 
console.log("Going to open a file!");
// Opening a File 
fd = fs.openSync('mytext.txt'); 
console.log(fd); 
console.log("File has opened successfully!");
// Reading the File
data = fs.readFileSync('mytext.txt');
console.log("Reading the File: " + data.toString());
console.log("\nClosing the File!");
//Synchronous Version to Close the File
fs.closeSync(fd) 
console.log("\n> File has Closed successfully!!");

To execute the above script file, type the following command on the terminal:

$ node close.js

The Output will look like as shown below:

Going to open a file!
3
File has opened successfully!
Reading the File: Hello! Welcome to TUTORIALANDEXAMPLE.COM Tutorials.
Learning is so easy with TUTORIALANDEXAMPLE.COM
Closing the File!
> File has Closed successfully!!
·        To create a Directory: fs.mkdir()

The File System module of Node.js has already defined an operation to create a directory using the fs.mkdir() method. Let’s try an example given below based on the fs.mkdir() method:

File: create_dir.js

const fs = require('fs');
console.log("Creating a Directory ...");
// Asynchronous version to create a Directory
fs.mkdir('/Node JS/Example', function(err) {
    if (err) {
        return console.error(err);
    };
        console.log("Node JS/Example has been created successfully!!");
});
// Synchronous version to create a Directory
fs.mkdirSync('/Node JS/Test');
console.log("Node JS/Test has been created successfully!!");

Now, to execute the above program, type the following command on the terminal:

$ node create_dir.js

The Output should look like:

Creating a Directory ...
Node JS/Test has been created successfully!!
Node JS/Example has been created successfully!!
·        To read a Directory: fs.readdir()

The File System module of Node.js has also defined the fs.readdir() method for reading a directory. The functioning of the fs.readdir() method can be understood with the help of an example given below:

File: read_dir.js

const fs = require('fs');
console.log("Reading the Directory: NODE JS ...");
// Asynchronous Version to read a directory
fs.readdir('/Node JS', function ( err, files ){
    if ( err ) {
        return console.error( err );
    };
    files.forEach( function (file){
        console.log( file );
    });
    console.log("/NODE JS Directory has been successfully read!!");
});

Now, to execute the above program, type the following command on the terminal:

$ node read_dir.js

The Output should look like, as shown below:

Reading the Directory: NODE JS ...
append.js
close.js
create.js   
Create_dir.js
delete.js   
Example     
mydoc.txt   
mytext.txt  
node_modules
open.js
package-lock.json
read.js
read.txt
read_dir.js
rename.js
stats.js
Test
truncate.js
/NODE JS Directory has been successfully read!!
·        To Remove a Directory: fs.rmdir()

The Node.js File System Module includes the fs.rmdir() method that allows the user to remove any directory from the system. Let’s try an example based on the fs.rmdir() method:

File: remove_dir.js

const fs = require('fs');
console.log('Deleting the Directory: Example');
// To remove a directory from the system
fs.rmdir( '/Node JS/Example', function (err){
    if ( err ){
        return console.error( err );
    }
    console.log("The directory has removed successfully!!");
});
// To read the director for verification
fs.readdir( '/Node JS/', function( err, docs ){
    if ( err ){
        return console.error( err );
    }
    docs.forEach( function (doc){
        console.log(doc);
    });
    console.log("Directory has been read successfully!!");
});

Now, to execute the above program, type the following command on the terminal:

$ node remove_dir.js

The Output should look like, as shown below:

Deleting the Directory: Example
The directory has removed successfully!!
append.js
close.js
create.js
Create_dir.js
delete.js
mydoc.txt
mytext.txt
node_modules
open.js
package-lock.json
read.js
read.txt
read_dir.js
remove_dir.js
rename.js
stats.js
Test
truncate.js
Directory has been read successfully!!