简体   繁体   English

如何在OS X上查看文件更改?

[英]How do I watch for file changes on OS X?

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? 我怎么做?

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

From my expericence, in some case files aren't only written but deleted then rewritten (the case for some plist files). 从我的经验来看,在某些情况下,文件不仅会被写入,而是被删除然后重写(一些plist文件的情况)。 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. 然后你必须稍微调整代码:在ordre中替换文件时再次调用方法以保持监视。

- (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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在OS X上创建IMServicePlugin? 没有关于文件结构的文档 - How do I create an IMServicePlugin on OS X? No documentation on file structure OS X当日期更改时,如何更新相对日期显示? - OS X How do I update relative date display when date changes? 如何在我的应用程序中接收在OS X中作为服务调用的文件路径? - How do I receive a file path in my app which is invoked as a service in os x? 当文件,图片等放在其停靠栏图标上时,如何让OS X应用程序做出反应? - How do I make an OS X application react when a file, picture, etc is dropped on its dock icon? OS X:如何使用NSRunLoop监视套接字读取事件? - OS X: how to watch socket read events with NSRunLoop? 如何在OS X中将subView添加到webView中,以便它可以滚动 - How do I add a subView to a webView in OS X so It will scroll 如何在OS X服务菜单中自动激活项目 - How do I automatically activate an item in the OS X Services Menu 如何在Mac OS X上获取默认临时目录? - How do I get the default temporary directory on Mac OS X? 如何在OS X中成功从钥匙串中删除项目? - How do I successfully delete an item from keychain in OS X? 在 OS X 中,如何检测当前活动的应用程序何时发生变化? - In OS X, how can I detect when the currently active application changes?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM