Node.js File System Module

I. What is Node.js File system module?

In our computer, data is organized and accesed through a file system. The Node.js file system module allows us to interact with the file system.

fs handles file system operations such as reading to and writing from files. There are synchronous and asynchronous methods in the library.

To include the File System module, use the require() method:

const fs = require("fs");

Some of the methods include:

  • fs.readFile(): reads files asynchronously
  • fs.writeFile(): writes data to files asynchronously
  • fs.rename(): renames the specified file

II. Working with files in Node.js

1. Read file

We use fs.readFile() method to read files on the computer.

This takes 2 argument:

  • The first argument is a relative path to the file we want to read
  • The second argument is a callback function that will fire when this is completed
const fs = require("fs");

fs.readFile("./docs/blog.txt", (err, data) => {
  if (err) throw err;
  console.log(data);
});

// Result: <Buffer 48 65 6c 6c 6f 2c 20 57 6f 72 6c 64>

When we run the file, it will return a buffer, which is a package of data.

To see our string data in text format, we can use toString() method:

const fs = require("fs");

fs.readFile("./docs/blog.txt", (err, data) => {
  if (err) throw err;
  console.log(data.toString());
});

// Result: Hello world

2. Write file

To write file, we use fs.writeFile() method. It takes 3 arguments:

  • The first argument is a relative path to the file we want to write to
  • The second argument is a text we want to write to this file
  • The third argument is a callback function

For example, we’d like to replace “Hello world” with “Hello there”:

const fs = require("fs");

fs.writeFile("./docs/blog.txt", "Hello there", () => {
  console.log("file was changed");
});

// Result: file was changed

The fs.writeFile() asynchronously writes data to the file, replacing the file if it already exists. If the file does not exist, a new file will be created.

For example, if we run the following code, we’ll see blog2.txt appears in our directory.

const fs = require("fs");

fs.writeFile("./docs/blog2.txt", "Hello there", () => {
  console.log("file was changed");
});

// Result: file was changed

3. Delete file

To delete file, we use fs.unlink() method. It takes 2 arguments:

  • The first argument is a relative path to the file we want to delete
  • The second argument is a callback function
const fs = require("fs");

fs.unlink("./docs/blog2.txt", (err) => {
  if (err) {
    console.log(err);
  }
  console.log("file deleted");
});

// Result: file deleted

4. Check if a file exists

We can check whether a file or a directory exists or not before deleting it with fs.existsSync() method.

const fs = require("fs");

if (fs.existsSync("./docs/blog2.txt")) {
  fs.unlink("./docs/blog2.txt", (err) => {
    if (err) {
      console.log(err);
    }
    console.log("file deleted");
  });
}

III. Working with directories

1. Create a directory

To create a new directory, we can use fs.mkdir() method. We’ll need to specify what directory to make and where.

const fs = require("fs");

fs.mkdir("./images", (err) => {
  if (err) {
    console.log(err);
  }
  console.log("directory created");
});

2. Check if a directory exists

We can check whether a directory exists or not before creating it with fs.existsSync() method.

const fs = require("fs");

if (!fs.existsSync("./images")) {
  fs.mkdir("./images", (err) => {
    if (err) {
      console.log(err);
    }
    console.log("folder created");
  });
}

3. Remove a directory

const fs = require("fs");

fs.rmdir("./images", (err) => {
  if (err) {
    console.log(err);
  }
  console.log("directory deleted");
});

Resources: Check fs Documentation for more methods.

IV. Stream

If a file is large, it can take a long time to read so we’ll waste time waiting. To avoid that, we can use Streams.

Using stream, we can start using the data before it has finished loading.

1. Read stream

To open a file as a readable stream, we can use fs.createReadStream(). It takes 2 arguments:

  • The first argument is the path of where we want to read and pass data from
  • The second argument is an object { encoding: "utf8" } so the stream will be in a readable format.

We’ll then create an event listener to whenever we create a chunk of data:

const fs = require("fs");

const readStream = fs.createReadStream("./docs/blog3.txt", {
  encoding: "utf8",
});

readStream.on("data", (chunk) => {
  console.log("--New Chunk--");
  console.log(chunk);
});

2. Write stream

We can use fs.createReadStream() to write data to a file a bit at a time.

For example, we’ll pass data of blog3 to blog4:

const fs = require("fs");

const readStream = fs.createReadStream("./docs/blog3.txt", {
  encoding: "utf8",
});
const writeStream = fs.createWriteStream("./docs/blog4.txt");

readStream.on("data", (chunk) => {
  writeStream.write(chunk);
});

V. Pipe

Using pipe, we can pass data from a readable to a writable stream in a much shorter way

const fs = require("fs");

const readStream = fs.createReadStream("./docs/blog3.txt", {
  encoding: "utf8",
});
const writeStream = fs.createWriteStream("./docs/blog4.txt");

readStream.pipe(writeStream);