Dart FileSystemEvent
last modified October 18, 2026
The FileSystemEvent class in Dart represents changes in the file
system. It's used with Directory.watch() to monitor files and directories.
FileSystemEvent provides information about create, modify, delete, and move
operations. It's part of Dart's dart:io library for I/O operations.
Basic Definition
FileSystemEvent is a sealed base class with concrete subclasses
for different event types. These include create, modify, delete, and move events.
Key properties include path, type, and (for move events) destination path. Events are delivered asynchronously through streams from Directory.watch().
Basic File Monitoring
This example shows basic file system monitoring using FileSystemEvent.
import 'dart:io';
void main() async {
var dir = Directory('watch_dir');
await dir.create();
var subscription = dir.watch().listen((event) {
print('Event type: ${event.runtimeType}');
print('Path: ${event.path}');
if (event is FileSystemMoveEvent) {
print('Destination: ${event.destination ?? '(unknown)'}');
}
});
await File('${dir.path}/newfile.txt').create();
await Future.delayed(Duration(seconds: 1));
await subscription.cancel();
}
We create a watcher for a directory, trigger one create event, and then cancel the subscription. The code prints the concrete event class and path, including special handling for move events.
$ dart main.dart Event type: FileSystemCreateEvent Path: watch_dir/newfile.txt
Filtering Specific Event Types
This example demonstrates filtering for specific file system event types.
import 'dart:io';
void main() async {
var dir = Directory('watch_dir');
await dir.create();
var seen = <String>{};
var subscription = dir.watch().listen((event) {
if (!seen.add('${event.type}:${event.path}')) return;
switch (event.type) {
case FileSystemEvent.create:
print('File created: ${event.path}');
break;
case FileSystemEvent.modify:
print('File modified: ${event.path}');
break;
case FileSystemEvent.delete:
print('File deleted: ${event.path}');
break;
}
});
var file = File('${dir.path}/test.txt');
await file.create();
await file.writeAsString('content');
await file.delete();
await Future.delayed(Duration(seconds: 1));
await subscription.cancel();
}
We watch a specific directory and handle different event types separately. This allows customized responses to different file system operations.
$ dart main.dart File created: watch_dir/test.txt File modified: watch_dir/test.txt
Handling Move Events
This example focuses on detecting and handling file move/rename operations.
import 'dart:io';
void main() async {
var dir = Directory('watch_dir');
await dir.create();
var subscription = dir.watch().listen((event) {
if (event is FileSystemMoveEvent) {
print('File moved/renamed:');
print('From: ${event.path}');
print('To: ${event.destination ?? '(unknown)'}');
print('Is directory: ${event.isDirectory}');
}
});
var file = await File('${dir.path}/old.txt').create();
await file.rename('${dir.path}/new.txt');
await Future.delayed(Duration(seconds: 1));
await subscription.cancel();
}
Move events are special as they include both source and destination paths. The destination is nullable because some platforms cannot always determine it, and the isDirectory property indicates if the moved item is a file or directory.
$ dart main.dart File moved/renamed: From: watch_dir/old.txt To: watch_dir/new.txt Is directory: false
Watching Recursively
This example shows how to monitor a directory and all its subdirectories.
import 'dart:io';
void main() async {
var dir = Directory('watch_dir');
await dir.create(recursive: true);
var subscription = dir.watch(recursive: true).listen((event) {
print('Event in ${event.isDirectory ? 'directory' : 'file'}:');
print('Path: ${event.path}');
print('Type: ${event.runtimeType}');
});
await Directory('${dir.path}/subdir').create();
await Future.delayed(Duration(seconds: 1));
await subscription.cancel();
}
The recursive flag asks the platform to extend monitoring to subdirectories. This works on Windows and macOS; on Linux Dart uses inotify without recursive watches, so only entries in the top directory are reported. We also check whether each event affects a file or directory.
$ dart main.dart Event in directory: Path: watch_dir/subdir Type: FileSystemCreateEvent
Error Handling in File Watching
This example demonstrates proper error handling for file system watching.
import 'dart:io';
void main() async {
var dir = Directory('nonexistent_dir');
await dir.create();
var subscription = dir.watch().listen(
(event) {
print('Event: ${event.runtimeType} at ${event.path}');
},
onError: (Object error) {
print('Error watching directory: $error');
},
);
await dir.delete();
await Future.delayed(Duration(seconds: 1));
await subscription.cancel();
}
The listener's onError callback receives asynchronous watcher
errors, such as an inaccessible path. We also cancel the subscription after the
watched directory is deleted.
$ dart main.dart Event: FileSystemDeleteEvent at nonexistent_dir
Best Practices
- Resource cleanup: Cancel subscriptions when no longer needed
- Error handling: Always handle potential I/O errors
- Performance: Be mindful of recursive watching on large trees
- Event batching: Some platforms may batch multiple changes
- Cross-platform: Behavior may vary between operating systems
Source
Dart FileSystemEvent Documentation
This tutorial covered Dart's FileSystemEvent class with practical examples showing file system monitoring, event handling, and error management.
Author
List all Dart tutorials.