Reputation: 94723
I have a file path to a specific file and I want to register to be notified whenever that file changes (its contents have been modified).
I have tried searching google and I can't find a clear answer. I have experimented with kqueue and NSWorkspace but have not had much success.
What is the proper way to do this?
Thanks!
Upvotes: 3
Views: 3764
Reputation: 22903
Thanks to a blog post from David Hamerick, I finally managed to detect any modification on a file:
+ (void)monitorFile:(NSString*) path {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
int fildes = open([path UTF8String], O_EVTONLY);
__block typeof(self) blockSelf = self;
__block dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fildes,
DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_EXTEND |
DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_LINK | DISPATCH_VNODE_RENAME |
DISPATCH_VNODE_REVOKE, queue);
dispatch_source_set_event_handler(source, ^{
unsigned long flags = dispatch_source_get_data(source);
if(flags & DISPATCH_VNODE_DELETE)
{
dispatch_source_cancel(source);
//
// DO WHAT YOU NEED HERE
//
[blockSelf monitorFile:path];
}
});
dispatch_source_set_cancel_handler(source, ^(void) {
close(fildes);
});
dispatch_resume(source);
}
Upvotes: 8
Reputation: 22817
I am using VDKQueue right now - author says it's a refactored and more performant version of UKKQueue.
Implementation was pretty straightforward:
VDKQueueDelegate
;VDKQueue*
ivar / property;VDKQueue:receivedNotification:forPath:
;addPath:notifyingAbout:
.Then just do your business in the delegate method.
Upvotes: 4