Monitoring a directory in Cocoa/Cocoa Touch
I am trying to find a way to monitor the contents of a directory for changes. I have tried two approaches.
- Use kqueue to monitor the directory
- Use GCD to monitor the directory
The problem I am encountering is that I can’t find a way to detect which file has changed. I am attempting to monitor a directory with potentially thousands of files in it and I do not want to call stat on every one of them to find out which ones changed. I also do not want to set up a separate dispatch source for every file in that directory. Is this currently possible?
Note: I have documented my experiments monitoring files with kqueue and GCD
Solutions Collect From Internet About “Monitoring a directory in Cocoa/Cocoa Touch”
My advice is to just bite the bullet and do a directory scan in another thread, even if you’re talking about thousands of files. But if you insist, here’s the answer:
There’s no way to do this without rolling up your sleeves and going kernel-diving.
Your first option is to use the FSEvents framework, which sends out notifications when a file is created, edited or deleted (as well as things to do with attributes). Overview is here, and someone wrote an Objective C wrapper around the API, although I haven’t tried it. But the overview doesn’t mention the part about events surrounding file changes, just directories (like with kqueue). I ended up using the code from here along with the header file here to compile my own logger which I could use to get events at the individual file level. You’d have to write some code in your app to run the logger in the background and monitor it.
Alternatively, take a look at the “fs_usage” command, which constantly monitors all filesystem activity (and I do mean all). This comes with Darwin already, so you don’t have to compile it yourself. You can use kqueue to listen for directory changes, while at the same time monitoring the output from “fs_usage”. If you get a notification from kqueue that a directory has changed, you can look at the output from fs_usage, see which files were written to, and check the filenames against the directory that was modified. fs_usage is a firehose, so be prepared to use some options along with Grep to tame it.
To make things more fun, both your FSEvents logger and fs_usage require root access, so you’ll have to get authorization from the user before you can use them in your OS X app (check out the Authorization Services Programming Guide for info on how to do it).
If this all sounds horribly complicated, that’s because it is. But at least you didn’t have to find out the hard way!
- UINavigationController without navigation bar?
- ScrollView not scrolling when dragging on buttons
- Migrate from RACSignal to ReactiveSwift or RAC5
- Framework linking error, image not found?
- How to make a photo zoom, setting aspect ratio and then zooming leaves white area in Swift?
- What's wrong with how I'm using NSDateFormatter?
- Blur specific part of an image (rectangular, circular)?
- How to pass multiple enum values as a function parameter
- Xcode: Display Login View in applicationDidBecomeActive
- Settings AVAudioTimePitchAlgorithmVarispeed for AVFoundationAudioSettings
- Show method definition/description in Xcode 4
- Expandable tableView in iphone
- local declaration hides instance variable warning
- Swift constants: Struct or Enum
- What is the correct way of init iVar variables in presence of ARC