Understanding Node.js File System Module

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, file path has to be provided as a first argument and a callback function that will be called with file data.

In 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 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 HTTP connection, reading the file and streaming it to 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 operation, 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 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 writable streams API fs.createWriteStream() to write data in chunks.

Checking 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, isFile() method on 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, size property tells 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 operation.

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.

Advertisements

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章