Working with directories is a fundamental task in many Node.js applications, including file management systems, log handlers, static file servers, build tools, and more. Node.js provides various ways to interact with directories using built-in modules such as fs, path, and fs/promises. This document covers how to perform a wide range of operations on directories including creating, reading, renaming, deleting, listing contents, checking existence, and navigating between directories.
Understanding how to manage directories programmatically enhances your ability to build robust file-based applications. We will explore both synchronous and asynchronous approaches to give a comprehensive understanding.
The fs (File System) module is used to interact with the file system in a traditional callback-based or synchronous manner.
Introduced in Node.js 10+, fs/promises enables the use of Promise-based asynchronous file system methods.
The path module helps in handling and transforming file paths across operating systems.
const fs = require('fs');
const fsPromises = require('fs/promises');
const path = require('path');
fs.mkdir('new-folder', (err) => {
if (err) {
return console.error("Error creating directory:", err);
}
console.log('Directory created successfully');
});
try {
fs.mkdirSync('new-folder-sync');
console.log('Directory created synchronously');
} catch (err) {
console.error(err);
}
async function createDirectory() {
try {
await fsPromises.mkdir('new-folder-promises');
console.log('Directory created using promises');
} catch (err) {
console.error(err);
}
}
createDirectory();
fs.mkdir('nested/dir/structure', { recursive: true }, (err) => {
if (err) throw err;
console.log('Nested directory created');
});
if (fs.existsSync('new-folder')) {
console.log('Directory exists');
} else {
console.log('Directory does not exist');
}
fs.access('new-folder', fs.constants.F_OK, (err) => {
console.log(err ? 'Does not exist' : 'Exists');
});
fs.readdir('new-folder', (err, files) => {
if (err) return console.error(err);
console.log('Files:', files);
});
try {
const files = fs.readdirSync('new-folder');
console.log('Directory contents:', files);
} catch (err) {
console.error(err);
}
async function readDir() {
try {
const files = await fsPromises.readdir('new-folder');
console.log(files);
} catch (err) {
console.error(err);
}
}
readDir();
fs.rename('new-folder', 'renamed-folder', (err) => {
if (err) return console.error(err);
console.log('Directory renamed');
});
try {
fs.renameSync('renamed-folder', 'final-folder');
console.log('Directory renamed synchronously');
} catch (err) {
console.error(err);
}
fs.rmdir('final-folder', (err) => {
if (err) return console.error(err);
console.log('Directory removed');
});
try {
fs.rmdirSync('final-folder');
console.log('Directory removed synchronously');
} catch (err) {
console.error(err);
}
async function deleteDir() {
try {
await fsPromises.rmdir('final-folder');
console.log('Directory deleted');
} catch (err) {
console.error(err);
}
}
deleteDir();
fs.rm('non-empty-folder', { recursive: true, force: true }, (err) => {
if (err) throw err;
console.log('Non-empty directory removed');
});
const fullPath = path.join(__dirname, 'dir', 'file.txt');
console.log(fullPath);
const absolute = path.resolve('dir', 'file.txt');
console.log(absolute);
console.log('Before:', process.cwd());
process.chdir('some-folder');
console.log('After:', process.cwd());
fs.stat('new-folder', (err, stats) => {
if (err) return console.error(err);
console.log('Is directory:', stats.isDirectory());
console.log('Created on:', stats.birthtime);
});
fs.readdir('your-folder', (err, items) => {
if (err) return console.error(err);
items.forEach(item => {
const fullPath = path.join('your-folder', item);
fs.stat(fullPath, (err, stats) => {
if (err) return console.error(err);
if (stats.isDirectory()) {
console.log(`${item} is a directory`);
} else {
console.log(`${item} is a file`);
}
});
});
});
Use fs.watch() or fs.watchFile() to monitor changes in a directory.
fs.watch('some-folder', (eventType, filename) => {
console.log(`Event: ${eventType}`);
console.log(`File changed: ${filename}`);
});
function readRecursively(dir) {
fs.readdir(dir, { withFileTypes: true }, (err, files) => {
if (err) return console.error(err);
files.forEach(file => {
const fullPath = path.join(dir, file.name);
if (file.isDirectory()) {
readRecursively(fullPath);
} else {
console.log('File:', fullPath);
}
});
});
}
readRecursively('base-folder');
const fsExtra = require('fs-extra');
fsExtra.ensureDir('new-dir')
.then(() => console.log('Directory ensured'))
.catch(err => console.error(err));
fsExtra.emptyDir('empty-me')
.then(() => console.log('Directory emptied'));
const glob = require('glob');
glob("**/*.js", function(err, files) {
if (err) console.error(err);
else console.log("JavaScript files:", files);
});
Working with directories in Node.js is a powerful capability that allows developers to automate, manipulate, and interact with the file system efficiently. From creating directories and reading their contents to renaming, removing, and watching for changes, Node.js provides a rich set of tools and APIs.
By mastering both synchronous and asynchronous approaches, leveraging promises for cleaner code, and using modules like fs and path correctly, developers can build robust, file-aware Node.js applications. Furthermore, with the addition of third-party tools like fs-extra and glob, even more advanced functionality becomes easily accessible.
A function passed as an argument and executed later.
Runs multiple instances to utilize multi-core systems.
Reusable blocks of code, exported and imported using require() or import.
nextTick() executes before setImmediate() in the event loop.
Starts a server and listens on specified port.
Node Package Manager β installs, manages, and shares JavaScript packages.
A minimal and flexible web application framework for Node.js.
A stream handles reading or writing data continuously.
It processes asynchronous callbacks and non-blocking I/O operations efficiently.
Node.js is a JavaScript runtime built on Chrome's V8 engine for server-side scripting.
An object representing the eventual completion or failure of an asynchronous operation.
require is CommonJS; import is ES6 syntax (requires transpilation or newer versions).
Use module.exports or exports.functionName.
Variables stored outside the code for configuration, accessed using process.env.
MongoDB, often used with Mongoose for schema management.
Describes project details and manages dependencies and scripts.
Synchronous blocks execution; asynchronous runs in background without blocking.
Allows or restricts resources shared between different origins.
Use try-catch, error events, or middleware for error handling.
Provides file system-related operations like read, write, delete.
Using event-driven architecture and non-blocking I/O.
Functions in Express that execute during request-response cycle.
A set of routes or endpoints to interact with server logic or databases.
Yes, it's single-threaded but handles concurrency using the event loop and asynchronous callbacks.
Middleware to parse incoming request bodies, like JSON or form data.
Copyrights © 2024 letsupdateskills All rights reserved