Nodejs Working With Fs File System Complete Guide

 Last Update:2025-06-22T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    7 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of NodeJS Working with fs File System

Node.js Working with fs File System

Node.js provides a robust, non-blocking fs (File System) module designed to facilitate file operations on the server-side environment seamlessly. The fs module allows you to perform actions like reading, writing, appending, deleting, and renaming files. This capability is pivotal for backend developers who need to manipulate local storage.

Essential Methods in the fs Module

  1. Synchronous vs. Asynchronous Operations

    • Asynchronous Methods: These methods do not block execution. Instead, they take a callback function as their final argument. Examples include:

      • fs.readFile(path, options, callback) – Reads the contents of a file asynchronously.
      • fs.writeFile(file, data, options, callback) – Writes data to a file, overwriting if it already exists.
      • fs.unlink(path, callback) – Deletes a file asynchronously.
      • fs.rename(oldPath, newPath, callback) – Renames a file asynchronously.
    • Synchronous Methods: These methods block execution until the operation completes. They should be used sparingly, especially in production environments, to avoid blocking the event loop. Corresponding synchronous versions of the above methods are:

      • fs.readFileSync(path, options)
      • fs.writeFileSync(file, data, options)
      • fs.unlinkSync(path)
      • fs.renameSync(oldPath, newPath)
  2. Reading Files

    • Using Callbacks:
      const fs = require('fs');
      const path = './data.txt';
      
      fs.readFile(path, 'utf8', (err, data) => {
        if (err) throw err;
        console.log(data);
      });
      
    • Using Promises (fs.promises):
      const fsp = require('fs/promises');
      const path = './data.txt';
      
      async function readFileAsync() {
        try {
          const data = await fsp.readFile(path, 'utf8');
          console.log(data);
        } catch (err) {
          console.error(err);
        }
      }
      
      readFileAsync();
      
    • Using Async/Await and util.promisify:
      const fs = require('fs');
      const util = require('util');
      const path = './data.txt';
      
      const readFile = util.promisify(fs.readFile);
      
      async function readFileUtilPromisify() {
        try {
          const data = await readFile(path, 'utf8');
          console.log(data);
        } catch (err) {
          console.error(err);
        }
      }
      
      readFileUtilPromisify();
      
  3. Writing Files

    • Using Callbacks:

      const fs = require('fs');
      const path = './output.txt';
      const content = 'Hello, world!';
      
      fs.writeFile(path, content, err => {
        if (err) throw err;
        console.log('The file has been saved!');
      });
      
    • Using Promises (fs.promises):

      const fsp = require('fs/promises');
      const path = './output.txt';
      const content = 'Hello, world!';
      
      async function writeFileAsync() {
        try {
          await fsp.writeFile(path, content);
          console.log('The file has been saved!');
        } catch (err) {
          console.error(err);
        }
      }
      
      writeFileAsync();
      
    • Using Async/Await and util.promisify:

      const fs = require('fs');
      const util = require('util');
      const path = './output.txt';
      const content = 'Hello, world!';
      
      const writeFile = util.promisify(fs.writeFile);
      
      async function writeFileUtilPromisify() {
        try {
          await writeFile(path, content);
          console.log('The file has been saved!');
        } catch (err) {
          console.error(err);
        }
      }
      
      writeFileUtilPromisify();
      
  4. Appending to Files

    • Append data to an existing file or create the file if it does not exist.

    • Using Callbacks:

      const fs = require('fs');
      const path = './output.txt';
      const content = '\nAppended text here!';
      
      fs.appendFile(path, content, 'utf8', err => {
        if (err) throw err;
        console.log('The text has been appended!');
      });
      
    • Using Promises (fs.promises):

      const fsp = require('fs/promises');
      const path = './output.txt';
      const content = '\nAppended text here!';
      
      async function appendFileAsync() {
        try {
          await fsp.appendFile(path, content, 'utf8');
          console.log('The text has been appended!');
        } catch (err) {
          console.error(err);
        }
      }
      
      appendFileAsync();
      
    • Using Async/Await and util.promisify:

      const fs = require('fs');
      const util = require('util');
      const path = './output.txt';
      const content = '\nAppended text here!';
      
      const appendFile = util.promisify(fs.appendFile);
      
      async function appendFileUtilPromisify() {
        try {
          await appendFile(path, content, 'utf8');
          console.log('The text has been appended!');
        } catch (err) {
          console.error(err);
        }
      }
      
      appendFileUtilPromisify();
      
  5. Deleting (unlinking) Files

    • The unlink() method is used for deleting files.

    • Using Callbacks:

      const fs = require('fs');
      const path = './output.txt';
      
      fs.unlink(path, err => {
        if (err) throw err;
        console.log(` ${path} was deleted`);
      });
      
    • Using Promises (fs.promises):

      const fsp = require('fs/promises');
      const path = './output.txt';
      
      async function deleteFileAsync() {
        try {
          await fsp.unlink(path);
          console.log(`${path} was deleted`);
        } catch (err) {
          console.error(err);
        }
      }
      
      deleteFileAsync();
      
    • Using Async/Await and util.promisify:

      const fs = require('fs');
      const util = require('util');
      const path = './output.txt';
      
      const unlink = util.promisify(fs.unlink);
      
      async function deleteFileUtilPromisify() {
        try {
          await unlink(path);
          console.log(`${path} was deleted`);
        } catch (err) {
          console.error(err);
        }
      }
      
      deleteFileUtilPromisify();
      
  6. Renaming Files

    • Rename a file from one path to another.

    • Using Callbacks:

      const fs = require('fs');
      const oldPath = './output-old.txt';
      const newPath = './output-new.txt';
      
      fs.rename(oldPath, newPath, err => {
        if (err) throw err;
        console.log('Rename complete!');
      });
      
    • Using Promises (fs.promises):

      const fsp = require('fs/promises');
      const oldPath = './output-old.txt';
      const newPath = './output-new.txt';
      
      async function renameFileAsync() {
        try {
          await fsp.rename(oldPath, newPath);
          console.log('Rename complete!');
        } catch (err) {
          console.error(err);
        }
      }
      
      renameFileAsync();
      
    • Using Async/Await and util.promisify:

      const fs = require('fs');
      const util = require('util');
      const oldPath = './output-old.txt';
      const newPath = './output-new.txt';
      
      const rename = util.promisify(fs.rename);
      
      async function renameFileUtilPromisify() {
        try {
          await rename(oldPath, newPath);
          console.log('Rename complete!');
        } catch (err) {
          console.error(err);
        }
      }
      
      renameFileUtilPromisify();
      
  7. Working with Directories

    • Creating Directories:

      • Using Callbacks:

        const fs = require('fs');
        const dirPath = './new-directory';
        
        fs.mkdir(dirPath, { recursive: true }, (err) => {
          if (err) throw err;
          console.log('Directory created successfully');
        });
        
      • Using Promises (fs.promises):

        const fsp = require('fs/promises');
        const dirPath = './new-directory';
        
        async function createDirectoryAsync() {
          try {
            await fsp.mkdir(dirPath, { recursive: true });
            console.log('Directory created successfully');
          } catch (err) {
            console.error(err);
          }
        }
        
        createDirectoryAsync();
        
      • Using Async/Await and util.promisify:

        const fs = require('fs');
        const util = require('util');
        const dirPath = './new-directory';
        
        const mkdir = util.promisify(fs.mkdir);
        
        async function createDirectoryUtilPromisify() {
          try {
            await mkdir(dirPath, { recursive: true });
            console.log('Directory created successfully');
          } catch (err) {
            console.error(err);
          }
        }
        
        createDirectoryUtilPromisify();
        
    • Reading Directories:

      • Using Callbacks:

        const fs = require('fs');
        const dirPath = './'; // Root directory
        
        fs.readdir(dirPath, (err, files) => {
          if (err) throw err;
          console.log(files);
        });
        
      • Using Promises (fs.promises):

        const fsp = require('fs/promises');
        const dirPath = './'; // Root directory
        
        async function readDirectoryAsync() {
          try {
            const files = await fsp.readdir(dirPath);
            console.log(files);
          } catch (err) {
            console.error(err);
          }
        }
        
        readDirectoryAsync();
        
      • Using Async/Await and util.promisify:

        const fs = require('fs');
        const util = require('util');
        const dirPath = './'; // Root directory
        
        const readdir = util.promisify(fs.readdir);
        
        async function readDirectoryUtilPromisify() {
          try {
            const files = await readdir(dirPath);
            console.log(files);
          } catch (err) {
            console.error(err);
          }
        }
        
        readDirectoryUtilPromisify();
        
    • Removing Directories:

      • Using Callbacks:

        const fs = require('fs');
        const dirPath = './new-directory';
        
        fs.rmdir(dirPath, { recursive: true }, err => {
          if (err) throw err;
          console.log(`${dirPath} removed successfully`);
        });
        
      • Using Promises (fs.promises):

        const fsp = require('fs/promises');
        const dirPath = './new-directory';
        
        async function removeDirectoryAsync() {
          try {
            await fsp.rm(dirPath, { recursive: true, force: true });
            console.log(`${dirPath} removed successfully`);
          } catch (err) {
            console.error(err);
          }
        }
        
        removeDirectoryAsync();
        
      • Using Async/Await and util.promisify:

        const fs = require('fs');
        const util = require('util');
        const dirPath = './new-directory';
        
        const rm = util.promisify(fs.rm);
        
        async function removeDirectoryUtilPromisify() {
          try {
            await rm(dirPath, { recursive: true, force: true });
            console.log(`${dirPath} removed successfully`);
          } catch (err) {
            console.error(err);
          }
        }
        
        removeDirectoryUtilPromisify();
        
  8. Checking File/Directory Existence

    • Using fs.exists() (Deprecated):

      • It is deprecated and discouraged in favor of checking existence before performing operations.
    • Checking Existence using Promises:

      const fsp = require('fs/promises');
      const path = './data.txt';
      
      async function checkFileExists() {
        try {
          await fsp.access(path);
          console.log('File exists');
        } catch (err) {
          console.log('File does not exist');
        }
      }
      
      checkFileExists();
      
    • Using Callbacks:

      const fs = require('fs');
      const path = './data.txt';
      
      fs.access(path, fs.constants.F_OK, (err) => {
        if (err) {
          console.log('File does not exist');
        } else {
          console.log('File exists');
        }
      });
      
  9. Watching Files

    • The fs.watch() method watches for changes on filename. A listener will be appended to the filename.

    • Implementation Example:

      const fs = require('fs');
      const path = './watch-this-file.txt';
      
      fs.watch(path, (eventType, filename) => {
        console.log(`Event type is: ${eventType}`);
        if (filename) {
          console.log(`Filename provided: ${filename}`);
        } else {
          console.log('Filename not provided');
        }
      });
      

Streamed File I/O

For handling large files effectively, Node.js recommends using streams. Streams are more efficient, particularly for large files, as they allow data to be processed piece by piece rather than loading everything into memory at once.

  • Reading Files with Streams:

    const fs = require('fs');
    const path = './large-data.txt';
    
    const readStream = fs.createReadStream(path, 'utf8');
    readStream.on('data', chunk => {
      console.log(chunk);
    });
    readStream.on('end', () => {
      console.log('Finished reading the file.');
    });
    readStream.on('error', err => {
      console.log('An error occurred.', err);
    });
    
  • Writing Files with Streams:

    const fs = require('fs');
    const writeStream = fs.createWriteStream('output-large-data.txt');
    
    writeStream.write('Here is some data.\n');
    writeStream.write('One more line added!\n');
    writeStream.end('This is the last line.');
    
    writeStream.on('finish', () => {
      console.log('File has been written successfully.');
    });
    
    writeStream.on('error', err => {
      console.log('An error occurred.', err);
    });
    

Buffered I/O

When working with binary data (like images or any other non-text files), use the Buffer class provided by Node.js.

Example Reading an Image File:

const fs = require('fs');
const path = './image.png';

fs.readFile(path, (err, data) => {
  if (err) throw err;
  console.log(data); // Logs Buffer object containing the image data
});

Example Writing Binary Data:

const fs = require('fs');
const data = Buffer.from('Some binary data here.');

fs.writeFile('./binary-output.bin', data, err => {
  if (err) throw err;
  console.log('Binary file has been saved.');
});

Handling Errors Gracefully

It is crucial to handle errors appropriately to ensure that applications remain stable, especially in production environments. Utilize try/catch blocks when using promises and callbacks to catch and handle any exceptions thrown during file operations.

Example Error Handling While Reading Files:

const fs = require('fs');
const path = './non-existent-file.txt';

fs.readFile(path, 'utf8', (err, data) => {
  if (err) {
    console.error('Error while reading the file:', err.message);
    return;
  }
  console.log(data);
});

// Using Promises & async/await for more readable code
const fsp = require('fs/promises');

async function safeReadFile() {
  try {
    const data = await fsp.readFile(path, 'utf8');
    console.log(data);
  } catch (err) {
    console.error('Error while reading the file:', err.message);
  }
}

safeReadFile();

Advanced Features: Watching Directories and Chmod

  • Watching Directories: Similar to watching files, directories can also be monitored for changes.

    const fs = require('fs');
    
    const watchDir = fs.watch('./directory-to-watch', (eventType, filename) => {
      if (filename) {
        console.log(`event type is: ${eventType}`);
        console.log(`filename provided: ${filename}`);
      } else {
        console.log('filename not provided');
      }
    });
    
  • Changing Permissions: Modify file permissions using chmod() or its promise-based chmod() counterpart in fs.promises.

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement NodeJS Working with fs File System

Example 1: Reading a File Synchronously

Step 1: Import the fs Module

The first step is to include the file system module. You can do this using the require function.

const fs = require('fs');

Step 2: Use the readFileSync Method

The readFileSync method reads the entire content of a file synchronously, meaning it blocks the execution until the file is read.

try {
    const data = fs.readFileSync('example.txt', 'utf8');
    console.log(data);
} catch (err) {
    console.error(err);
}

Full Code for Reading a File Synchronously

const fs = require('fs');

try {
    // Read the file synchronously
    const data = fs.readFileSync('example.txt', 'utf8');
    
    // Log the file contents to the console
    console.log('File Contents:', data);
} catch (err) {
    // Catch any errors that might occur during reading the file
    console.error('Error reading file:', err);
}

Example 2: Reading a File Asynchronously

Step 1: Import the fs Module

Again, we start by importing the fs module.

const fs = require('fs');

Step 2: Use the readFile Method

The readFile method reads the entire content of a file asynchronously. It requires a callback function to handle the result or error.

fs.readFile('example.txt', 'utf8', (err, data) => {
    if (err) {
        console.error(err);
        return;
    }
    console.log(data);
});

Full Code for Reading a File Asynchronously

const fs = require('fs');

// Read the file asynchronously
fs.readFile('example.txt', 'utf8', (err, data) => {
    if (err) {
        // Log any errors that might occur during reading the file
        console.error('Error reading file:', err);
        return;
    }
    
    // Log the file contents to the console
    console.log('File Contents:', data);
});

Example 3: Writing a File Synchronously

Step 1: Import the fs Module

const fs = require('fs');

Step 2: Use the writeFileSync Method

The writeFileSync method writes data to a file synchronously, which means it blocks the execution until the data is written.

try {
    fs.writeFileSync('output.txt', 'Hello, World!');
    console.log('The file has been saved!');
} catch (err) {
    console.error(err);
}

Full Code for Writing a File Synchronously

const fs = require('fs');

try {
    // Write data to the file synchronously
    fs.writeFileSync('output.txt', 'Hello, World!');
    
    // Log success message to console
    console.log('The file has been saved!');
} catch (err) {
    // Catch and log any errors that occur writing to the file
    console.error('Error writing to file:', err);
}

Example 4: Writing a File Asynchronously

Step 1: Import the fs Module

const fs = require('fs');

Step 2: Use the writeFile Method

The writeFile method writes data to a file asynchronously. A callback function should be provided to handle the completion or error.

fs.writeFile('output.txt', 'Hello, World!', (err) => {
    if (err) {
        console.error(err);
        return;
    }
    console.log('The file has been saved!');
});

Full Code for Writing a File Asynchronously

const fs = require('fs');

// Write data to a file asynchronously
fs.writeFile('output.txt', 'Hello, World!', (err) => {
    if (err) {
        // Log any errors that might occur writing the file
        console.error('Error writing to file:', err);
        return;
    }
    
    // Log success message to console
    console.log('The file has been saved!');
});

Example 5: Checking If a File Exists

Step 1: Import the fs Module

const fs = require('fs');

Step 2: Using the accessSync Method (Synchronously)

You can use the accessSync method to check whether a file exists or not. If the file does not exist, an error will be thrown.

Top 10 Interview Questions & Answers on NodeJS Working with fs File System

Top 10 Questions and Answers: Node.js Working with fs File System

1. What is the fs module in Node.js, and how do you use it?

To use the fs module, you first need to require it:

const fs = require('fs');

2. How can you read a file asynchronously using fs.readFile?

Reading a file asynchronously prevents your application from blocking while waiting for the file to be read. Use fs.readFile method for this purpose:

fs.readFile('filename.txt', 'utf8', (err, data) => {
    if (err) throw err;
    console.log(data);
});

This reads a file named filename.txt in UTF-8 format and logs its content to the console.

3. How do you handle errors properly when using fs asynchronous methods?

Errors in asynchronous fs methods are typically handled using callback functions. Always check if an error exists before proceeding:

fs.readFile('filename.txt', 'utf8', (err, data) => {
    if (err) {
        console.error(err);
        return;
    }
    // Proceed without errors
    console.log(data);
});

4. Can you explain the difference between synchronous and asynchronous file operations in Node.js?

In Node.js, fs module provides both synchronous and asynchronous methods for file operations:

  • Asynchronous: Methods like fs.readFile, fs.writeFile operate non-blocking. This means the operations do not stop your application from running other code while they are being executed.

  • Synchronous: Methods like fs.readFileSync, fs.writeFileSync stop your application until the operation is completed. Synchronous methods should be avoided in production environments because they can significantly slow down your app if used for time-intensive tasks.

5. How can you write to a file asynchronously in Node.js?

To write to a file asynchronously, use fs.writeFile method:

fs.writeFile('output.txt', 'Hello, Node.js!', (err) => {
    if (err) throw err;
    console.log('Data written successfully!');
});

This writes Hello, Node.js! to a file named output.txt. If the file does not exist, it will be created.

6. What happens if you write to a file that already exists?

If you use fs.writeFile() on a file that already exists, its contents will be overwritten by the new data provided.

7. How do you append data to a file in Node.js?

Appending data to a file is done using fs.appendFile:

fs.appendFile('log.txt', '\nNew line of text', (err) => {
    if (err) throw err;
    console.log('Data appended to file.');
});

Appending data allows you to add content to the end of a file without overwriting its existing data.

8. How can you check if a file exists in Node.js?

You can use the fs.exists() method, but it has been deprecated. Instead, you should use fs.access(path, fs.F_OK, callback) to check file existence:

const fs = require('fs');

fs.access('path/to/file', fs.constants.F_OK, (err) => {
    if (err) {
        console.log('File does not exist');
        return;
    }
    console.log('File exists');
});

9. How do you delete a file in Node.js?

Deleting a file can be done with the fs.unlink function:

fs.unlink('path/to/file.txt', (err) => {
    if (err) throw err;
    console.log('File was deleted.');
});

This asynchronously deletes a file at the specified path.

10. How can I create a directory in Node.js using fs.mkdir?

Creating directories is necessary when organizing saved files. Use the fs.mkdir function to create a new directory:

fs.mkdir('/path/to/dir', { recursive: true }, (err) => {
    if (err) throw err;
    console.log('Directory was created successfully!');
});

Setting the recursive option to true ensures that no error will be thrown if the directory already exists, and also allows creating nested directories.

You May Like This Related .NET Topic

Login to post a comment.