Question

I need to monitor a large list of files for deletion or movement. And this list can change dynamically quite a number of times. Is it possible to change the paths to watch of the FSEventStreamContext while the monitoring is in progress?

Is there any other better way to achieve this instead of using FSEvents.

Was it helpful?

Solution

You can also use GCD dispatch sources to observe filesystem events.
An advantage over the (older) FSEvents API is, that dispatch sources notify via block-based handlers.

You can also specify a mask for the events that you are interested in (e.g. DISPATCH_VNODE_DELETE|DISPATCH_VNODE_RENAME for renames and deletions)

    NSURL* url = [NSURL fileURLWithPath:[@"~/Desktop/test.txt" stringByExpandingTildeInPath]];
    dispatch_queue_t observerQueue = dispatch_queue_create("filesystem-observer-queue", 0);
    int fileDescriptor = open([url fileSystemRepresentation], O_EVTONLY);
    dispatch_source_vnode_flags_t eventMask = DISPATCH_VNODE_DELETE|DISPATCH_VNODE_RENAME;
    dispatch_source_t fileSystemSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fileDescriptor, eventMask, observerQueue);
    dispatch_source_set_event_handler(fileSystemSource, ^{
        dispatch_source_vnode_flags_t eventSourceFlag = dispatch_source_get_data(fileSystemSource);
        if(eventSourceFlag & DISPATCH_VNODE_DELETE)
        {
            NSLog(@"delete");
            dispatch_source_cancel(fileSystemSource);
        }
        else if(eventSourceFlag & DISPATCH_VNODE_RENAME)
        {
             NSLog(@"rename");
        }
        NSLog(@"Change at %@ of type %lu", url, eventSourceFlag);
    });
    dispatch_source_set_cancel_handler(fileSystemSource, ^{
        close(fileDescriptor);
    });
    dispatch_resume(fileSystemSource);

Some notes:

  • The above code just shows the general idea. It does not try to cover all edge cases.
  • When you observe a directory, you only get one notification that something changed, but no information about the affected file(s) or the change type.
  • DISPATCH_VNODE_DELETE means true deletion (e.g. not the Finders move to trash)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top