Cocoa监视文件以进行修改

时间:2012-09-09 23:32:21

标签: objective-c macos cocoa filesystems

我有一个指向特定文件的文件路径,我想注册,以便在该文件发生更改(其内容已被修改)时收到通知。

我试过搜索谷歌,但我找不到明确的答案。我已经尝试过kqueue和NSWorkspace,但没有取得多大成功。

这样做的正确方法是什么?

谢谢!

2 个答案:

答案 0 :(得分:7)

感谢David Hamerick的blog post,我终于设法检测到文件的任何修改:

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

答案 1 :(得分:4)

我现在正在使用VDKQueue - 作者说它是UKKQueue的重构且更高效的版本。

实施非常简单:

  • 让您的控制器成为VDKQueueDelegate;
  • 声明VDKQueue* ivar / property;
  • 设置委托方法VDKQueue:receivedNotification:forPath:;
  • 初始化队列并将其委托设置为控制器本身;
  • 使用addPath:notifyingAbout:添加要观看的资源。

然后在委托方法中开展业务。