【问题标题】:Cocoa Monitor a file for modificationsCocoa 监控文件以进行修改
【发布时间】:2012-09-02 20:32:36
【问题描述】:

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

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

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

谢谢!

【问题讨论】:

    标签: objective-c macos cocoa filesystems


    【解决方案1】:

    感谢 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);
    }
    

    【讨论】:

    • path 编辑文件时,它似乎总是返回DISPATCH_VNODE_RENAME
    • 在路径编辑文件时,它似乎总是返回 DISPATCH_VNODE_RENAME
    【解决方案2】:

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

    实现非常简单:

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

    那就用委托方法做你的事情吧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-03
      • 2010-09-11
      相关资源
      最近更新 更多