macos - 如何快速监控文件夹中的新文件?

标签 macos swift

如何在不进行轮询(效率非常低)的情况下快速监控文件夹中的新文件?我听说过 kqueue 和 FSEvents 等 API,但我不确定是否可以快速实现它们?

最佳答案

GCD 似乎是可行的方法。 NSFilePresenter 类无法正常工作。它们有故障、损坏,而且 Apple 在过去 4 年里都不愿意修复它们。可能会被弃用。

这是一个非常好的帖子,它描述了这项技术的要点。

"Handling Filesystem Events with GCD" , 大卫哈姆里克

从网站引用的示例代码。我将他的 C 代码翻译成 Swift。

    let fildes = open("/path/to/config.plist", O_RDONLY)

    let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
    let source = dispatch_source_create(
        DISPATCH_SOURCE_TYPE_VNODE,
        UInt(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,
        {
            //Reload the config file
        })

    dispatch_source_set_cancel_handler(source,
        {
            //Handle the cancel
        })

    dispatch_resume(source);

    ...

        // sometime later
        dispatch_source_cancel(source);

作为引用,这里是作者发布的另一个 QA:


如果您对观看目录感兴趣,这里是另一篇描述它的帖子。

"Monitoring a Folder with GCD"Cocoanetics 上。 (不幸的是,我找不到作者的名字,我很抱歉没有署名)

唯一明显的区别是获取文件描述符。这使得目录的事件通知文件描述符。

_fileDescriptor = open(path.fileSystemRepresentation(), O_EVTONLY)

更新

之前我声称 FSEvents API 不工作,但我错了。该 API 运行良好,如果您有兴趣在深层文件树上观看,那么它的简单性可能比 GCD 更好。

无论如何,FSEvents不能用在纯Swift程序中。因为它需要传递C回调函数,而Swift目前不支持(Xcode 6.1.1)。然后我不得不回退到 Objective-C 并再次包装它。

此外,任何此类 API 都是完全异步的。这意味着实际文件系统状态在您收到通知时可能会有所不同。那么精确或准确的通知并没有真正的帮助,仅对标记脏标志有用。

更新2

我最终为 Swift 编写了一个围绕 FSEvents 的包装器。 这是我的工作,希望对您有所帮助。

关于macos - 如何快速监控文件夹中的新文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24150061/

相关文章:

python - 调用 fork() 时,多处理导致 Python 崩溃并给出错误可能已在另一个线程中进行

cocoa - 在系统范围内更改 cocoa 单词补全 - 可能吗?

ios - 核心数据关系在具有共同属性的实体上具有 header 实体

objective-c - NSButton 在 NSImageView 上显示时出现渲染问题

macos - NSImageView 和调整窗口大小

ios - 将 UITapGestureRecognizer 添加到 UIPickerView 的 subview

swift - Swift 3.0 的 stringByReplacingOccurencesOfString()

swift - 后退按钮图片 - 在 Swift 中它叫什么?

ios - 无法在 WatchOS 3 中更新 Apple Watch 并发症

Swift 如何在文件中创建全局变量,但不共享给其他文件