The core API of the fs module
Core APIs of the fs Module
The Node.js fs
module provides core functionality for file system operations, allowing developers to interact with the file system. This module includes both synchronous and asynchronous APIs, supporting various functions such as file reading/writing, directory operations, and permission management. The fs
module is one of the most fundamental and frequently used modules in Node.js.
File Reading and Writing Operations
Asynchronous File Reading
fs.readFile()
is the most commonly used method for asynchronous file reading. It takes the file path, encoding format, and a callback function as parameters:
const fs = require('fs');
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
Synchronous File Reading
The synchronous version, fs.readFileSync()
, blocks the event loop until the file is fully read:
try {
const data = fs.readFileSync('example.txt', 'utf8');
console.log(data);
} catch (err) {
console.error(err);
}
Streaming File Reading
For large files, it's recommended to use streaming:
const readStream = fs.createReadStream('largefile.txt', 'utf8');
readStream.on('data', (chunk) => {
console.log('Received chunk:', chunk.length);
});
File Writing Operations
Asynchronous File Writing
fs.writeFile()
is used for asynchronous file writing:
fs.writeFile('output.txt', 'Hello Node.js', 'utf8', (err) => {
if (err) throw err;
console.log('File written successfully');
});
Appending Content
fs.appendFile()
appends content to the end of a file:
fs.appendFile('log.txt', `${new Date()}: New log entry\n`, (err) => {
if (err) console.error(err);
});
Streaming Writing
For large files, use writable streams:
const writeStream = fs.createWriteStream('bigfile.txt');
for (let i = 0; i < 10000; i++) {
writeStream.write(`Line ${i}\n`);
}
writeStream.end();
File System Operations
Checking File Existence
fs.existsSync()
synchronously checks if a file exists:
if (fs.existsSync('config.json')) {
console.log('Config file exists');
}
Getting File Status
fs.stat()
retrieves file metadata:
fs.stat('package.json', (err, stats) => {
if (err) throw err;
console.log(`Size: ${stats.size} bytes`);
console.log(`Is file: ${stats.isFile()}`);
});
Renaming Files
fs.rename()
renames or moves a file:
fs.rename('oldname.txt', 'newname.txt', (err) => {
if (err) throw err;
});
Directory Operations
Creating Directories
fs.mkdir()
creates a new directory:
fs.mkdir('new-directory', { recursive: true }, (err) => {
if (err) throw err;
});
Reading Directory Contents
fs.readdir()
lists files and subdirectories in a directory:
fs.readdir('./', (err, files) => {
if (err) throw err;
files.forEach(file => console.log(file));
});
Deleting Directories
fs.rmdir()
deletes an empty directory, while fs.rm()
can delete recursively:
fs.rm('empty-dir', { recursive: true }, (err) => {
if (err) console.error(err);
});
File Watching
Monitoring File Changes
fs.watch()
monitors changes to files or directories:
const watcher = fs.watch('config.json', (eventType, filename) => {
console.log(`Event type: ${eventType}, File: ${filename}`);
});
// Stop watching
setTimeout(() => watcher.close(), 10000);
Advanced File Operations
File Descriptor Operations
Use file descriptors for low-level operations:
fs.open('data.bin', 'r+', (err, fd) => {
if (err) throw err;
const buffer = Buffer.alloc(1024);
fs.read(fd, buffer, 0, buffer.length, 0, (err, bytes) => {
if (err) throw err;
console.log(buffer.slice(0, bytes).toString());
fs.close(fd, (err) => { if (err) throw err; });
});
});
Modifying File Permissions
fs.chmod()
changes file permissions:
fs.chmod('script.sh', 0o755, (err) => {
if (err) throw err;
});
Performance Optimization Tips
Using Promises for Batch Operations
Convert callback-style APIs to Promises:
const { promisify } = require('util');
const readFileAsync = promisify(fs.readFile);
async function processFiles() {
try {
const data = await readFileAsync('data.json');
console.log(JSON.parse(data));
} catch (err) {
console.error(err);
}
}
Using the fs-extra Module
fs-extra
provides additional convenience methods:
const fse = require('fs-extra');
// Copy an entire directory
fse.copy('/path/to/source', '/path/to/dest')
.then(() => console.log('Copy complete'))
.catch(err => console.error(err));
Error Handling Best Practices
Properly Handling ENOENT Errors
Error handling when a file doesn't exist:
fs.readFile('missing.txt', (err, data) => {
if (err) {
if (err.code === 'ENOENT') {
console.log('File not found');
} else {
throw err;
}
}
});
Resource Cleanup
Ensure file descriptors are properly closed:
let fd;
try {
fd = fs.openSync('temp.txt', 'w');
// File operations...
} finally {
if (fd !== undefined) fs.closeSync(fd);
}
Practical Use Cases
Reading Configuration Files
async function loadConfig() {
try {
const config = await fs.promises.readFile('config.json', 'utf8');
return JSON.parse(config);
} catch (err) {
if (err.code === 'ENOENT') {
return {}; // Return default config
}
throw err;
}
}
Logging System
class Logger {
constructor(logFile) {
this.logFile = logFile;
this.stream = fs.createWriteStream(logFile, { flags: 'a' });
}
log(message) {
const entry = `[${new Date().toISOString()}] ${message}\n`;
this.stream.write(entry);
}
}
Combining with the Path Module
Path Resolution and File Operations
const path = require('path');
function findConfigFile(dir) {
const configPath = path.join(dir, 'config.json');
if (fs.existsSync(configPath)) {
return configPath;
}
const parentDir = path.dirname(dir);
if (parentDir !== dir) {
return findConfigFile(parentDir);
}
return null;
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:常见Stream应用场景
下一篇:同步与异步文件操作