Xamarin Forms使用FileSystemWatcher监控应用内目录报错求助
Hey there! Let’s break down why your FileSystemWatcher is throwing errors when monitoring directories in iOS/Android apps, plus go through reliable alternative methods since mobile environments have unique constraints that desktop-focused tools like FileSystemWatcher don’t handle well.
Common Causes of FileSystemWatcher Errors & Fixes
First, let’s troubleshoot the immediate error you’re seeing:
Incorrect Directory Path
Mobile app internal directories don’t use fixed, hardcoded paths. For example:- On Android, use
Context.filesDir(internal storage) orContext.getExternalFilesDir(null)(scoped external storage) instead of writing a static path. - On iOS, you can only access directories within your app’s sandbox, like
NSDocumentDirectory—useEnvironment.GetFolderPath(Environment.SpecialFolder.MyDocuments)(in .NET) orFileManager.default.urls(for:in:).first(in Swift) to get the correct path.
Using a wrong or non-existent path will almost always trigger an error.
- On Android, use
Permission Restrictions
- Android: If monitoring external storage, you need
READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGEpermissions (and dynamic permission requests for Android 6+). For Android 10+, scoped storage rules mean you can’t access arbitrary external directories—stick to your app’s dedicated external storage folder. - iOS: Your app can only access its own sandbox directories. Trying to monitor paths outside the sandbox will fail immediately due to Apple’s security restrictions.
- Android: If monitoring external storage, you need
Limited Mobile Support for FileSystemWatcher
Let’s be real:FileSystemWatcherwas built for Windows desktop systems. Its implementation in cross-platform frameworks (like Xamarin or .NET MAUI) is incomplete or unreliable on mobile. iOS and Android have their own native file change notification systems thatFileSystemWatcherdoesn’t fully integrate with, leading to unexpected errors or no events at all.
Reliable Alternative Directory Monitoring Methods
Since FileSystemWatcher isn’t the best fit for mobile, here are native cross-platform-friendly alternatives:
Android: Use FileObserver
Android’s native FileObserver is designed explicitly for monitoring file system changes. You can extend it to listen for specific events:
public class DirectoryWatcher extends FileObserver { public DirectoryWatcher(String directoryPath) { // Listen for create, delete, and modify events super(directoryPath, FileObserver.CREATE | FileObserver.DELETE | FileObserver.MODIFY); } @Override public void onEvent(int event, String filePath) { switch (event) { case FileObserver.CREATE: // Handle new file/directory created break; case FileObserver.DELETE: // Handle file/directory deleted break; case FileObserver.MODIFY: // Handle file content modified break; } } }
To use it:
// Get your app's internal directory path String targetDir = getFilesDir().getAbsolutePath(); DirectoryWatcher watcher = new DirectoryWatcher(targetDir); watcher.startWatching(); // Stop watching when done // watcher.stopWatching();
If you’re using .NET MAUI/Xamarin, you can wrap this native code in a dependency service to call it from shared code.
iOS: Use GCD File System Events or NSFilePresenter
iOS offers two robust options:
- GCD File System Events (lightweight and straightforward):
guard let directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return } let fileDescriptor = open(directoryURL.path, O_EVTONLY) let queue = DispatchQueue.global(qos: .background) let fileMonitor = DispatchSource.makeFileSystemObjectSource( fileDescriptor: fileDescriptor, eventMask: [.write, .delete, .create], queue: queue ) fileMonitor.setEventHandler { let events = fileMonitor.data if events.contains(.create) { // Handle file/directory creation } if events.contains(.delete) { // Handle deletion } if events.contains(.write) { // Handle modification } } fileMonitor.resume()
NSFilePresenter: Better for tracking changes to specific files/directories across app instances or iCloud sync, but requires implementing a protocol.
Cross-Platform Wrapper (for .NET MAUI/Xamarin)
If you want a unified API across platforms, create a shared interface (e.g., IDirectoryWatcher) and implement it using the native methods above for each platform. You can also check existing plugins (like Plugin.FileSystemWatcher)—just make sure they’re actively maintained and compatible with your framework version.
内容的提问来源于stack exchange,提问作者Hikari

