Directory operations
File System Basics
Node.js provides the fs
module for handling file system operations. This module includes both synchronous and asynchronous methods, with asynchronous methods generally being preferred as they do not block the event loop. To use the fs
module, you first need to require it:
const fs = require('fs');
const fsPromises = require('fs').promises; // Promise version
Creating Directories
Creating directories is one of the most basic tasks in directory operations. Node.js provides the mkdir()
and mkdirSync()
methods to achieve this.
// Asynchronously create a directory
fs.mkdir('new-directory', (err) => {
if (err) throw err;
console.log('Directory created successfully');
});
// Synchronously create a directory
try {
fs.mkdirSync('new-directory-sync');
console.log('Directory created successfully (synchronous)');
} catch (err) {
console.error(err);
}
// Create a directory using Promises
async function createDir() {
try {
await fsPromises.mkdir('new-directory-promise');
console.log('Directory created successfully (Promise)');
} catch (err) {
console.error(err);
}
}
createDir();
Recursively Creating Directories
Sometimes you need to create a nested directory structure. You can use the recursive
option:
// Recursively create directories
fs.mkdir('parent/child/grandchild', { recursive: true }, (err) => {
if (err) throw err;
console.log('Recursive directories created successfully');
});
Reading Directory Contents
Reading directory contents is a common operation, achievable with the readdir()
method:
// Asynchronously read a directory
fs.readdir('./', (err, files) => {
if (err) throw err;
console.log('Directory contents:', files);
});
// Synchronously read a directory
try {
const files = fs.readdirSync('./');
console.log('Directory contents (synchronous):', files);
} catch (err) {
console.error(err);
}
// Read a directory using Promises
async function readDir() {
try {
const files = await fsPromises.readdir('./');
console.log('Directory contents (Promise):', files);
} catch (err) {
console.error(err);
}
}
readDir();
Getting Directory Details
Sometimes you need to get detailed information about a directory, such as creation time or modification time:
// Get directory status
fs.stat('some-directory', (err, stats) => {
if (err) throw err;
console.log('Is directory:', stats.isDirectory());
console.log('Creation time:', stats.birthtime);
console.log('Modification time:', stats.mtime);
});
Renaming Directories
To rename a directory, use the rename()
method:
// Rename a directory
fs.rename('old-name', 'new-name', (err) => {
if (err) throw err;
console.log('Directory renamed successfully');
});
Deleting Directories
There are several methods for deleting directories, depending on whether the directory is empty:
// Delete an empty directory
fs.rmdir('empty-directory', (err) => {
if (err) throw err;
console.log('Empty directory deleted successfully');
});
// Recursively delete a non-empty directory
fs.rm('non-empty-directory', { recursive: true }, (err) => {
if (err) throw err;
console.log('Non-empty directory deleted successfully');
});
Practical Directory Operation Tips
Checking if a Directory Exists
function directoryExists(path) {
try {
return fs.statSync(path).isDirectory();
} catch (err) {
return false;
}
}
Traversing a Directory Tree
function walkDir(dir, callback) {
fs.readdirSync(dir).forEach(f => {
let dirPath = path.join(dir, f);
let isDirectory = fs.statSync(dirPath).isDirectory();
isDirectory ? walkDir(dirPath, callback) : callback(path.join(dir, f));
});
}
walkDir('./', file => console.log(file));
Creating a Temporary Directory
const os = require('os');
const path = require('path');
const tempDir = path.join(os.tmpdir(), 'my-temp-dir');
fs.mkdirSync(tempDir);
Error Handling in Directory Operations
Proper error handling is crucial in directory operations:
fs.readdir('/nonexistent', (err, files) => {
if (err) {
if (err.code === 'ENOENT') {
console.error('Directory does not exist');
} else {
console.error('Unknown error occurred:', err);
}
return;
}
console.log(files);
});
Performance Considerations
When dealing with a large number of directory operations, performance becomes a key factor:
- Synchronous methods block the event loop and should be avoided in performance-critical applications.
- For batch operations, consider using streams or worker queues.
- For frequently accessed directories, you can cache the directory contents.
// Using a worker queue for heavy directory operations
const { Worker, isMainThread, workerData } = require('worker_threads');
if (isMainThread) {
const worker = new Worker(__filename, {
workerData: { dir: './large-directory' }
});
} else {
processDir(workerData.dir);
}
function processDir(dir) {
// Handle heavy directory tasks
}
Cross-Platform Considerations
Different operating systems handle directories differently:
- Windows uses backslashes () as path separators, while Unix uses forward slashes (/).
- Path case sensitivity varies across systems.
- Use the
path
module to handle paths and avoid these issues.
const path = require('path');
// Cross-platform path joining
const fullPath = path.join('dir', 'subdir', 'file.txt');
Advanced Directory Monitoring
Node.js provides the fs.watch()
method to monitor directory changes:
// Monitor directory changes
const watcher = fs.watch('./watched-dir', (eventType, filename) => {
console.log(`Event type: ${eventType}`);
if (filename) {
console.log(`Filename: ${filename}`);
}
});
// Stop monitoring
setTimeout(() => {
watcher.close();
}, 10000);
Combining Directory Operations with Streams
Combining directory operations with streams can efficiently handle large numbers of files:
const { Readable } = require('stream');
class DirectoryStream extends Readable {
constructor(dir) {
super({ objectMode: true });
this.dir = dir;
this.files = fs.readdirSync(dir);
this.index = 0;
}
_read() {
if (this.index < this.files.length) {
this.push(path.join(this.dir, this.files[this.index++]));
} else {
this.push(null);
}
}
}
const dirStream = new DirectoryStream('./large-dir');
dirStream.on('data', file => console.log(file));
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn