Watch File Changes
How to monitor file system changes in real time.
Note: This guide follows English-language naming conventions and terminology standards common in international development teams. Examples use English identifiers and comments to maximize compatibility across codebases and tooling.
Overview
File system watchers react to create, modify, delete, and rename events in real time. They power hot-reload dev servers, log tailers, and sync tools. This recipe shows cross-platform implementations in Python, JavaScript, and Java.
When to Use
Use this resource when:
- Building development servers that reload on code changes
- Monitoring log directories for new files to process
- Triggering pipelines when upload folders receive files
Solution
Python
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class Handler(FileSystemEventHandler):
def on_modified(self, event):
if not event.is_directory:
print(f"Modified: {event.src_path}")
observer = Observer()
observer.schedule(Handler(), path='./watched', recursive=True)
observer.start()
try:
while True:
pass
except KeyboardInterrupt:
observer.stop()
observer.join()
JavaScript
const fs = require('fs');
// Watch a file or directory
const watcher = fs.watch('./watched', { recursive: true }, (eventType, filename) => {
console.log(`${eventType}: ${filename}`);
});
// Cleanup
process.on('SIGINT', () => watcher.close());
Java
import java.nio.file.*;
public class FileWatcher {
public static void watch(Path path) throws Exception {
WatchService watchService = FileSystems.getDefault().newWatchService();
path.register(watchService,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_DELETE);
while (true) {
WatchKey key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
System.out.println(event.kind() + ": " + event.context());
}
key.reset();
}
}
}
Explanation
Watchers register with the OS kernel, which then pushes events to your process rather than requiring expensive polling. Python watchdog abstracts inotify (Linux), FSEvents (macOS), and ReadDirectoryChangesW (Windows). Node.js fs.watch delegates to the most efficient native API per platform. Java NIO WatchService uses the same underlying OS mechanisms through a standardized API.
Variants
| Technology | Approach | Notes |
|---|---|---|
| Python | watchdog library | Cross-platform, handles edge cases like rapid renames |
| JavaScript | chokidar npm package | More reliable than fs.watch on macOS and Windows |
| Java | Apache Commons IO FileAlterationMonitor | Polling fallback for older JDKs |
Best Practices
- Debounce rapid events (editors often trigger multiple writes)
- Always handle the
errorevent /WatchServiceexceptions - Use recursive watches sparingly; they consume OS resources
- Filter by file extension to ignore temp files (e.g.,
.tmp,.swp) - Run watchers in a dedicated thread or process to avoid blocking
Common Mistakes
- Assuming
modifyevents fire only once per save (editors may trigger many) - Not cleaning up watcher resources on shutdown, causing resource leaks
- Watching network drives with native APIs that don’t support them
- Ignoring
renameevents, which appear as separate create + delete on some OSes - Processing files immediately on
createbefore the writer has closed them
Frequently Asked Questions
Can I watch remote or network paths?
Native watchers generally do not support network shares. Use polling libraries like chokidar with usePolling: true or FileAlterationMonitor as fallbacks.
Why do I get duplicate events?
Many text editors write files atomically (create temp, rename), triggering multiple events. Debounce with a small delay (e.g., 100 ms) before acting.
How many files can I watch at once?
OS limits vary. Linux inotify has a per-user max_user_watches limit (default ~8K). macOS FSEvents scales to millions. Avoid recursive watches on huge trees.
Related Resources
Read Large Files
How to read large files efficiently without running out of memory.
RecipeWrite Large Files
How to write large files efficiently using buffered and streaming output.
RecipeFile Upload Validation
How to handle file uploads securely with size, type, and content validation.
RecipeGenerate PDFs
How to generate PDF documents programmatically from HTML, templates, or raw data.
RecipeProcess Large Files with Streams
How to read, transform, and write large files efficiently using streams without loading entire files into memory in Python, Node.js, and Java.