如何在不进行轮询(效率非常低)的情况下快速监控文件夹中的新文件?我听说过 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/