Node.js – File System

Node.js File System

In previous Tutorials, we discussed Buffers, then Streams. File system is related as well.

File System allows you to read and write data to file in your OS. This is made possible by the Node File System module(fs).

We would examine the following sub-topics:

  1. Asynchronous vs Synchronous Operation
  2. Opening a File
  3. Getting File Information
  4. Writing to a File
  5. Reading a File
  6. Closing a File
  7. Truncating a File
  8. Deleting a File
  9. Creating a Directory

 

1. Synchronous vs Asynchronous Operations

the fs module provides methods that both synchronous and asynchronous forms.

For example, we learnt of readFile() and readFileSync() when we learn of callbacks. The readFile() is the asynchronous equivalent of readFileSync().

Asynchronous methods take callback functions as the last parameter. There are many benefits of using asynchronous method. It provides for better performance since it does not tie down the thread.

The code below reads data asynchronously from a file named testoutput.txt.

//Demonstrating Async and Sync operations
var fs = require("fs");

//Read file Asynchronously
fs.readFile('D:/nodefiles/testinput.txt', function (err, data) {
   if (err) {
      return console.error(err);
   }
   console.log("Reading Asynchronously: " + data.toString());
});

//Reading Synchronously
var data = fs.readFileSync('D:/nodefiles/testinput.txt');
console.log("Reading Synchronously: " + data.toString());

console.log("End of Program");

 

2. Opening a File

You can open a file in your computer using the syntax below.

fs.open(path, flags[, mode], callback)

Where

  • path − is the string having file name including path.
  • flags − Flags indicate the behavior of the file to be opened. All possible values have been mentioned in the table below.
  • mode − sets the file mode (permission and sticky bits). But only if the file was created. The defaults are 0666, readable and writeable.
  • callback − is the callback function to call after a successful operation. It gets two arguments (err, fd).

 

The flags parameter can be any of the following:

SN. Flag and brief description
1 r

Opens the file for reading. An exception occurs if the file does not exist.

2 r+

Opens the file for reading and writing. An exception occurs if the file does not exist in the directory.

3 rs

Opens the file for reading in synchronous mode.

4 rs+

Opens the file for reading and writing, asking the OS to open it synchronously. To be used  with caution.

5 w

Opens the file for writing. The file is created (if it does not exist). Otherwise it is truncated (if it exists).

6 wx

Like ‘w’ but fails if the path exists.

7 w+

Open file for reading and writing. The file is created (if it does not exist) or truncated (if it exists).

8 wx+

Like ‘w+’ but fails if path already exists.

9 a

Opens the file for appending. The file is created if it does not already exist.

10 ax

Like ‘a’ but fails if the path exists.

11 a+

Opens the file for reading and appending. The file is created if it does not already exist.

12 ax+

Like ‘a+’ but fails if the the path already exists.

The code below opens a file for reading and writing the flag is r+

var fs = require("fs");

//  Opening a File Asynchronous
console.log("Opening a file...");
fs.open('D:/nodefiles/testinput.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File was  opened successfully!");     
});

 

3. Getting File Information

Node.js allows you to retrieve the properties of a file in your system. This is done using the stat() method of fs object. The syntax is given below:

fs.stat(path, callback)

where

  • path − In the path to the file
  • callback − is the callback function to execute. It gets two arguments (err, stats) where stats is an object of fs.Stats type.

Other methods available in the fs.Stats class in given below. This method is used to get additional metadata of the file

 

SN. Method and brief description
1 stats.isFile()

Returns true if file of a simple file type.

2 stats.isDirectory()

Returns true if the specified path is type of a directory.

3 stats.isBlockDevice()

Returns true if file type of a block device, otherwise, it returns false.

4 stats.isCharacterDevice()

Returns true if file type of a character device, otherwise, it returns false.

5 stats.isSymbolicLink()

Returns true if file type of a symbolic link, otherwise, it returns false.

6 stats.isFIFO()

Returns true if file type of a FIFO, otherwise, it returns false.

7 stats.isSocket()

Returns true if file type of asocket, otherwise, it returns false.

Let’s now apply some of these methods using the code below:

var fs = require("fs");

console.log("Getting the file information!");
fs.stat('D:/nodefiles/testinput.txt', function (err, stats) {
   if (err) {
      return console.error(err);
   }
   console.log(stats);
   console.log("The file information was retrieved!");
   
   // Check file type
   console.log("isDirectory ? " + stats.isDirectory());   
   console.log("isFile ? " + stats.isFile()); 
});

If you run the code, you will have the output below.(provided the file exists!)

 

  rdev: 0,
  blksize: undefined,
  ino: 1407374884044874,
  size: 62,
  blocks: undefined,
  atimeMs: 1569248643316.3845,
  mtimeMs: 1569245334975.0874,
  ctimeMs: 1569245334975.0874,
  birthtimeMs: 1568998209028.1128,
  atime: 2019-09-23T14:24:03.316Z,
  mtime: 2019-09-23T13:28:54.975Z,
  ctime: 2019-09-23T13:28:54.975Z,
  birthtime: 2019-09-20T16:50:09.028Z }
The file information was retrieved!
isDirectory ? false
isFile ? true

 

4. Writing to a File

You can write to a file using the syntax below:

fs.writeFile(filename, data[, options], callback)

If the file already exists, then the method will overwrite the file.

The parameters are explained as follows:

  • path − is the string having the file path.
  • data − is the String or Buffer to be written into the specified file.
  • options − The third parameter is an object which will hold {encoding, mode, flag}. By default. encoding is utf8, mode is octal value 0666. and flag is ‘w’
  • callback − is the callback function which gets a single parameter err that returns an error in case of any writing error.

The code below would read and write into a file:

var fs = require("fs");

console.log("This is going to write into an existing file");
fs.writeFile('D:/nodefiles/nodefiles/input.txt', 'The best Tuorials ever!', function(err) {
   if (err) {
      return console.error(err);
   }
   
   console.log("Data was written successfully!");
   console.log("Now, let's read the data");
   
   fs.readFile('D:/nodefiles/testinput.txt', function (err, data) {
      if (err) {
         return console.error(err);
      }
      console.log("Reading asynchronously: " + data.toString());
   });
});

 

5. Reading a File

You can also read the content of a file using the syntax below:

fs.read(fd, buffer, offset, length, position, callback)

 

This methods uses a file descriptor, fd to read the file. The file descriptor object is returned by the open() method. However, to read the file directly using the filename, then you should use the readFile method.

The parameters to the read() method are:

  • fd − This is the file descriptor returned by fs.open() method
  • buffer − This is the buffer object the data will be written to.
  • offset − This is the offset in the buffer where the writing will start.
  • length − This is an integer that specifies the number of bytes to be read.
  • position − This is an integer that specifies where to begin reading from in the file. If position is null, then data will be read from the current file position.
  • callback − This is the callback function to be called when data is read. It takes three arguments, (err, bytesRead, buffer).

The example below demonstrates the read() operation:

var fs = require("fs");
var mybuffer = new Buffer.alloc(2048);

console.log("Opening an existing file for read-write");
fs.open('D:/nodefiles/testinput.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File was opened successfully");

   console.log("Starting file read operation"); 
   fs.read(fd, mybuffer, 0, mybuffer.length, 0, function(err, bytes){
      if (err){
         console.log(err);
      }
      console.log(bytes + " bytes read");
      
      // Print only read read bytes using the slice method.
      if(bytes > 0){
         console.log(mybuffer.slice(0, bytes).toString());
      }
   });
});

 

6. Closing a File

It is generally a good practice close files that were opened before exiting the program. To close a file, you use the close method. This takes two parameters: the file description, and a callback. The syntax is given below:

fs.close(fd, callback)

As an exercise, try to open a file, then close it back.

 

7. Truncating a File

To truncate a file simply means to change the length of the file. The amount by which to truncate(in bytes) is given as a parameter to the truncate() function. A callback is provided as well. If the length provided is shorter than the file’s current length, then the file is truncated to the new length. If the length provided is longer, then the file is padded by appending null bytes.

The syntax for truncate is:

fs.ftruncate(fd, len, callback)

The callback take just one parameter: err, an exception object.

 

8. Deleting a File

To delete a file, use the unlink() function. The syntax is given below.

fs.unlink(path, callback)

The callback take just one parameter: err, an exception object.

 

9. Creating a directory

You can create a directory in your file system using the syntax below:

fs.mkdir(path[, mode], callback)

where:

  • path − This is the directory to be created. The name is including path.
  • mode − This is the directory permission to be set for the new directory. The defaults is 0777.
  • callback − This is the callback function to execute. One argument is provided, which is the possible exception at the completion of the callback.

The code below creates a directory called node_dir in drive D:/nodefiles

var fs = require("fs");

console.log("Create directory in D:/nodefiles/node_dir");
fs.mkdir('D:/nodefiles/node_dir',function(err) {
   if (err) {
      return console.error(err);
   }
   console.log("Directory ws created successfully!");
});

If you run the code, you will see that the directory is created as shown in the figure below:

Node.js directory