阿里云主机折上折
  • 微信号
Current Site:Index > File monitoring function

File monitoring function

Author:Chuan Chen 阅读数:36594人阅读 分类: Node.js

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

  1. Set a reasonable polling interval: For fs.watchFile, intervals that are too short can cause performance issues.
  2. Avoid excessive monitoring: Only monitor necessary files and directories.
  3. 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

  1. Windows systems are case-insensitive to filenames.
  2. macOS requires handling system files like .DS_Store.
  3. 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

上一篇:文件描述符

下一篇:目录操作

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.