{{announcement.body}}
{{announcement.title}}

Understanding Node.js File System Module

DZone 's Guide to

Understanding Node.js File System Module

The file system module in Node.js allows you to work programmatically with the file system on an operating system.

· Web Dev Zone ·
Free Resource

A file system is a mechanism that controls how data is stored, accessed, and managed on an operating system. The file system module in Node.js allows you to work programmatically with the file system on an operating system.

Using file system (fs) module, we can perform read, write, delete, and many more operations. Let us look at some of the most important operations.

Prerequisites

Before we starting diving into file system operations, we need to import the fs module.

const fs = require("fs");

Reading Files Synchronously and Asynchronously

The fs module provides simple methods to read files: fs.readFile() and fs.readFileSync(). The fs.readFile() is for reading file asynchronously and fs.readFileSync() is for reading files synchronously.

fs.readFile('file.txt', function(err, data) {
    if (err) return callback(err);

    // If succeeded, print the contents.
    console.log(data);
});

Here, the file path has to be provided as a first argument and a callback function that will be called with file data.

In the case of fs.readFileSync(), pass the file path as an argument.

const data = fs.readFileSync('test.txt', "utf8"); 
console.log(data);

utf8 is the default encoding, but we can specify any custom encoding that we need as a second parameter in both the methods.

Both the methods read the entire file content in memory before returning the data. This could pose problems when we are reading large files. To handle these situations, it is recommended to use Streams using the fs module.

Reading Files Through Streams

Often, we have to deal with large files. The read operation could take quite a bit of time and utilize more memory. In such a scenario, we can use streams. We can read the file using and serve it over HTTP connection as soon as a chunk of data is ready to be sent.

const http = require('http')
const fs = require('fs')

const server = http.createServer((req, res) => {
  const stream = fs.createReadStream('test.txt')
  stream.pipe(res)
})
server.listen(3000, () => {
    console.log(`Server running at port 3000`)
})

Here, we are establishing an HTTP connection, reading the file, and streaming it to an HTTP client. pipe() is used for piping the file stream to the HTTP response.

Writing Files Synchronously and Asynchronously

The simplest way to write a file is to call fs.writeFile() which is an asynchronous operation.

fs.writeFile('file.txt', "Hello world", function(err) {
    if (err) return callback(err);

    // If succeeded, print the message.
    console.log("file created successfully!")
});

In synchronous write operations, we write as follows:

try {
  const file = fs.writeFileSync('test.txt', "Hello world");
} catch (err) {
  console.error(err)
}

By default, these API calls will override the content if it's already present. We can override this behavior by specifying a flag in the options parameter as follows:

{ flag: 'a+' }

When it comes to writing large data, we could get into issues with memory efficiency. Like readable streams, we also have a writable streams API, fs.createWriteStream(), to write data in chunks.

Checking the Status of a File

We can inspect the details of a file using fs.stat() and fs.statSync().

fs.stat('test.txt', (err, stats) => {
    if (err) {
      console.error(err)
      return
    }
    console.log(stats.isFile());
    console.log(stats.isSymbolicLink());
    console.log(stats.isDirectory());
    console.log(stats.size);
  });
const status = fs.statSync('test.txt');

  console.log(status.isFile());
  console.log(status.isSymbolicLink());
  console.log(status.isDirectory());
  console.log(status.size);

Here, the isFile() method on the stats or status variable tells if it is a file. Similarly, isDirectory() tells whether it is a directory. isSymbolicLink() tells if the file is symbolic link. Finally, the size property tells the size of the file.

Deleting a File or a Symbolic Link

We can remove a file or a symbolic link asynchronously. The method accepts only file path and the callback function.

fs.unlink('test.txt', (err) => {
  if (err) throw err;
  console.log('test.txt was removed');
});

This method does not work on the directory. We can use fs.rmdir() instead.

For a synchronous operation, we have fs.unlinkSync().

fs.unlinkSync('text.txt');

Renaming a File

A file can be renamed using fs.rename(). Here, it takes old file name, new file name, and a callback function as arguments.

fs.rename('file.txt', 'hello.txt', (err) => {
  if (err) throw err;
  console.log('Rename complete!');
});

Similarly, we have fs.renameSync() for synchronous operations.

Wrapping Up

We just covered some of the most commonly used API methods in this article. There are many more methods in fs module. Check here for the complete documentation.

Here is the GitHub repository for the examples used in this article.

Topics:
web dev ,node.js ,node.js tutorial ,synchronous ,asynchronous

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}