File monitoring function
File Monitoring Functionality
File monitoring functionality allows developers to listen for changes in the file system and trigger callback functions when files are modified, deleted, or created. Node.js provides two methods, fs.watch
and fs.watchFile
, to implement this feature, which is suitable for scenarios such as log monitoring, automatic builds, and hot reloading.
Basic Usage of fs.watch
fs.watch
is a file monitoring API provided by Node.js, based on the underlying operating system's event notification mechanism (such as inotify or kqueue). It is more efficient than fs.watchFile
, but some platforms may have compatibility issues.
const fs = require('fs');
// Monitor a single file
const watcher = fs.watch('example.txt', (eventType, filename) => {
console.log(`Event type: ${eventType}`);
if (filename) {
console.log(`Filename: ${filename}`);
}
});
// Close the watcher
setTimeout(() => {
watcher.close();
console.log('Stopped monitoring the file');
}, 10000);
Event Types of fs.watch
fs.watch
may trigger the following event types:
'rename'
: The file is renamed or deleted'change'
: The file content is modified'error'
: An error occurred
fs.watch('target.txt', (eventType, filename) => {
if (eventType === 'rename') {
console.log('File was renamed or deleted');
} else if (eventType === 'change') {
console.log('File content was modified');
}
});
Recursive Monitoring with fs.watch
Starting from Node.js 10.5.0, fs.watch
supports recursive monitoring of entire directory trees:
fs.watch('project', { recursive: true }, (eventType, filename) => {
console.log(`Detected changes in the project directory: ${filename}`);
});
Usage of fs.watchFile
fs.watchFile
checks for file state changes through polling. While less efficient, it offers better compatibility:
fs.watchFile('data.json', { interval: 100 }, (curr, prev) => {
if (curr.mtime !== prev.mtime) {
console.log('File modification time has changed');
}
});
Third-Party Library chokidar
For more complex file monitoring needs, the popular third-party library chokidar can be used:
const chokidar = require('chokidar');
// Initialize the watcher
const watcher = chokidar.watch('src/**/*.js', {
ignored: /(^|[\/\\])\../, // Ignore dot files
persistent: true
});
// Add event listeners
watcher
.on('add', path => console.log(`File added: ${path}`))
.on('change', path => console.log(`File modified: ${path}`))
.on('unlink', path => console.log(`File deleted: ${path}`));
// Close the watcher
process.on('SIGINT', () => watcher.close());
Performance Optimization Recommendations
- Set a reasonable polling interval: For
fs.watchFile
, intervals that are too short can cause performance issues. - Avoid excessive monitoring: Only monitor necessary files and directories.
- Use debouncing: Merge events during high-frequency modifications.
let debounceTimer;
fs.watch('large.log', (event, filename) => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
processFileChanges(filename);
}, 200);
});
Practical Application Examples
Automatic Development Server Restart
const { spawn } = require('child_process');
let serverProcess = startServer();
fs.watch('app.js', () => {
serverProcess.kill();
serverProcess = startServer();
console.log('Server restarted');
});
function startServer() {
return spawn('node', ['app.js'], { stdio: 'inherit' });
}
Real-Time Style Reloading
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
fs.watch('styles.css', () => {
wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send('reload-css');
}
});
});
Cross-Platform Considerations
- Windows systems are case-insensitive to filenames.
- macOS requires handling system files like
.DS_Store
. - Linux systems need to be aware of inotify monitoring limits.
// Check and increase inotify limits
if (process.platform === 'linux') {
require('child_process').exec('sysctl fs.inotify.max_user_watches', (err, stdout) => {
console.log(`Current inotify limit: ${stdout}`);
});
}
Error Handling Strategies
File monitoring may encounter various errors, which need to be handled properly:
const watcher = fs.watch('important.txt', (event, filename) => {
// Handle events
});
watcher.on('error', err => {
console.error('Watcher error:', err);
// Attempt to re-establish monitoring
setTimeout(() => setupWatcher(), 1000);
});
File Monitoring and Version Control
When working with version control systems like Git, note the following:
// Ignore changes in the .git directory
chokidar.watch('project', {
ignored: path => path.includes('.git')
});
Advanced Pattern Matching
Use glob patterns for more flexible file matching:
const glob = require('glob');
glob.watch('src/**/*.{js,jsx}', (err, files) => {
if (err) throw err;
console.log('Matched files:', files);
});
Resource Cleanup
Ensure file watchers are properly closed when the process exits:
const cleanUp = () => {
watcher.close();
// Other cleanup tasks
};
process.on('exit', cleanUp);
process.on('SIGINT', cleanUp);
process.on('uncaughtException', cleanUp);
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn