Node: List Files in a Directory

Introduction

Working with files is a common task with any programming language. File manipulation requires us to know their location. One of the most fundamental ways to interact with files is to list files in a directory.

In this article, we'll be using Node.js and the built-in fs module as well as the directory-tree module from NPM to list all files from a directory.

We'll read a directory, files, located at the same place our app.js file is in:

09/10/2020  01:27 PM               332 app.js
09/10/2020  01:24 PM    <DIR>          files

The directory contains:

files
│   anotherDirectory
│   └── fileInDirectory.txt
└── textFile.txt
└── anotherTextFile.txt

directory-tree

directory-tree is a handy NPM module that takes care of this task for us and formats the output nicely. First, let's install it:

$ npm install directory-tree

Now, let's import it into our script and supply it with our directory's location:

const dirTree = require("directory-tree");

const tree = dirTree('./files/');
console.log(tree);

The tree constant now contains the information we'd like to access. This code results in:

{
  path: './files/',
  name: 'files',
  children: [
    {
      path: 'files\\anotherDirectory',
      name: 'anotherDirectory',
      children: [Array],
      size: 8,
      type: 'directory'
    },
    {
      path: 'files\\anotherTextFile.txt',
      name: 'anotherTextFile.txt',
      size: 2218,
      extension: '.txt',
      type: 'file'
    },
    {
      path: 'files\\textFile.txt',
      name: 'textFile.txt',
      size: 7,
      extension: '.txt',
      type: 'file'
    }
  ],
  size: 2233,
  type: 'directory'
}

We can also specify the extensions we'd like to filter based on, using the dirTree() function:

const tree = dirTree('./files/', {extensions:/\.js$/});
console.log(tree);

This would return an empty result since there are no JS files in the files directory.

fs.readdir()

The easiest way to read files from a directory without external modules is with the help of the readdir() function. It's asynchronous and returns an array containing file names in the directory you've specified.

Let's go ahead and list the files from the files directory:

const directory = './files/';
const fs = require('fs');

fs.readdir(directory, (err, files) => {
    files.forEach(file => {
        console.log(file);
    });
});

Here, we've specified the directory constant, pointing to the files folder, after which, we've imported the fs module.

Then, we've supplied the directory to the readdir() function and logged their name via a callback. This results in:

anotherDirectory
anotherTextFile.txt
textFile.txt
textFile.txt - Shortcut.lnk

Note: The readdir() function also reads directories, but without an indication as to whether it's a directory or a file. A file without an extension looks the same as a directory in this case.

However, we can use the fs.lstatSync() function to help us out with this:

const directory = './files/';
const path = require('path');
const fs = require('fs');

fs.readdir(directory, (err, files) => {
  files.forEach(file => {
    if (fs.lstatSync(path.resolve(directory, file)).isDirectory()) {
      console.log('Directory: ' + file);
    } else {
      console.log('File: ' + file);
    }
  });
});

Using isDirectory(), we've checked if what we're encountering at the given path is a directory or a file. This now results in:

Directory: anotherDirectory
File: anotherTextFile.txt
File: file
File: textFile.txt

fs.readdirSync()

The readdirSync() function is virtually the same as the readdir() function, but it reads synchronously, instead of asynchronously.

It works in the very same way as the previous approach - it just handles the operation synchronously:

const directory = './files/';
const path = require('path');
const fs = require('fs');

fs.readdirSync(directory).forEach(file => {
  if (fs.lstatSync(path.resolve(directory, file)).isDirectory()) {
    console.log('Directory: ' + file);
  } else {
    console.log('File: ' + file);
  }
});

Here, we've done the same thing we've done before. Checking for files and directories, changing the flow slightly based on the results. This code prints out:

Directory: anotherDirectory
File: anotherTextFile.txt
File: file
File: textFile.txt

Conclusion

In this article, we've gone over a few ways to list files in a directory in Node.js We've started off with directory-tree, an NPM package built for this purpose, after which we've used the built-in fs module and its readdir() and readdirSync() functions to list the files.