fs
(filesystem) module, which provides functions to interact with the file system in a synchronous or asynchronous manner. In this blog post, we will explore various methods to list files in a directory and present code examples for each scenario.
Table of Contents
Synchronous Listing of Files
Listing files synchronously means that the operation will block the Node.js event loop until it completes. This approach can be used for simple scripts where the blocking nature is not a concern. Here’s an example:
const fs = require('fs'); // Synchronize listing of files in a directory try { const files = fs.readdirSync('/path/to/directory'); console.log(files); } catch (error) { console.error('Error reading directory:', error); }
Output:
['file1.txt', 'file2.txt', 'subdirectory']
The code above uses readdirSync()
to read the contents of a directory and returns an array of file and directory names.
Asynchronous Listing of Files
Asynchronous operations are non-blocking and are particularly important in a Node.js environment, especially for IO-bound tasks. Here’s how you can list files asynchronously:
const fs = require('fs'); // Asynchronous listing of files in a directory fs.readdir('/path/to/directory', (error, files) => { if (error) { console.error('Error reading directory:', error); return; } console.log(files); });
Output:
['file1.txt', 'file2.txt', 'subdirectory']
This code snippet uses readdir()
for an asynchronous file listing. The function takes a callback with two arguments: an error
and an array of files
.
Recursive Listing of Files
To get a list of files in a directory and all its subdirectories (recursively), you will need to create a recursive function since Node.js does not provide a built-in recursive directory listing function. Let’s look at an example:
const fs = require('fs'); const path = require('path'); function listFilesRecursively(dir, fileList = []) { const files = fs.readdirSync(dir); files.forEach((file) => { if(fs.statSync(path.join(dir, file)).isDirectory()) { fileList = listFilesRecursively(path.join(dir, file), fileList); } else { fileList.push(path.join(dir, file)); } }); return fileList; } const fileList = listFilesRecursively('/path/to/directory'); console.log(fileList);
Output:
['/path/to/directory/file1.txt', '/path/to/directory/subdirectory/file2.txt']
The listFilesRecursively
function recursively lists the files by checking if an item is a directory with fs.statSync
and then recursively calling itself if it is.
Filtering Results
You may only be interested in files with a specific extension or that match certain criteria. Here’s how to filter the file list:
const fs = require('fs'); const files = fs.readdirSync('/path/to/directory'); const filteredFiles = files.filter(file => file.endsWith('.txt')); console.log(filteredFiles);
Output:
['file1.txt', 'file2.txt']
The code above uses Array.prototype.filter
to only include files that end with the .txt
extension.
Error Handling
Proper error handling is crucial when working with file operations to avoid application crashes and handle any unexpected issues. The above examples include basic error handling using try-catch for synchronous operations and error callbacks for asynchronous operations.
Conclusion
In this tutorial, we’ve covered how to effectively retrieve a list of files in a directory using Node.js, in both synchronous and asynchronous manners, as well as how to recursively list files and apply filters to the results. By understanding these techniques, you can manage files and directories within your Node.js applications more efficiently.
References