How do I watch for file changes on OS X?

对着背影说爱祢 提交于 2019-12-09 07:08:33

问题


I would like to be notified of writes into a given file – without polling, without having to read from the file and without having to monitor the parent directory and watch the file modification time stamps. How do I do that?


回答1:


I couldn’t find a simple example, so I’m contributing what I came up with for future reference:

@interface FileWatch ()
@property(assign) dispatch_source_t source;
@end

@implementation FileWatch
@synthesize source;

- (id) initWithPath: (NSString*) path targetQueue: (dispatch_queue_t) queue block: (dispatch_block_t) handler
{
    self = [super init];

    int descriptor = open([path fileSystemRepresentation], O_EVTONLY);
    if (descriptor < 0) {
        return nil;
    }

    [self setSource:dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, descriptor, DISPATCH_VNODE_WRITE, queue)];
    dispatch_source_set_event_handler(source, handler);
    dispatch_source_set_cancel_handler(source, ^{
        close(descriptor);
    });

    dispatch_resume(source);
    return self;
}

- (void) dealloc
{
    if (source) {
        dispatch_source_cancel(source);
        dispatch_release(source);
        source = NULL;
    }
}

@end



回答2:


From my expericence, in some case files aren't only written but deleted then rewritten (the case for some plist files). Then you have to adapt the code a little bit : calling the method again when the files gets replaced in ordre to keep the monitoring.

- (void) myMonitoringMethodWithPath: :(NSString*) path
        __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);
                                          //Do some stuff

                                          if(flags & DISPATCH_VNODE_DELETE)
                                          {
                                              [blockSelf myMonitoringMethodWithPath:path];

                                          }
                                      });
    dispatch_source_set_cancel_handler(source, ^(void) 
                                       {
                                           close(fildes);
                                       });
    dispatch_resume(source);
}


来源:https://stackoverflow.com/questions/11447824/how-do-i-watch-for-file-changes-on-os-x

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!