如何在没有轮询的情况下在swift中监视新文件的文件夹(这是非常低效的)?我听说过像kqueue和FSEvents这样的API - 但我不确定是否可以在swift中实现它们?
Eon*_*nil 12
GCD似乎是要走的路.NSFilePresenter类无法正常工作.他们是马车,破损,苹果过去4年不愿意修理它们.可能会被弃用.
这是一篇非常好的帖子,描述了这种技术的基本要素.
"使用GCD处理文件系统事件",作者:David Hamrick.
网站引用的示例代码.我将他的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);
Run Code Online (Sandbox Code Playgroud)
作为参考,这是作者发布的另一个QA:
如果你对观看目录感兴趣,这里有另一篇描述它的帖子.
"监视文件夹GCD"上Cocoanetics.(不幸的是,我找不到作者的名字.我很遗憾没有归属)
唯一明显的区别是获取文件描述符.这使得目录的仅事件通知文件描述符成为可能.
_fileDescriptor = open(path.fileSystemRepresentation(), O_EVTONLY)
Run Code Online (Sandbox Code Playgroud)
以前我声称FSEventsAPI不起作用,但我错了.API工作得非常好,如果你对在深层文件树上观看感兴趣,那么它比GCD更简单.
无论如何,FSEvents不能用于纯Swift程序.因为它需要传递C回调函数,而Swift目前不支持它(Xcode 6.1.1).然后我不得不回到Objective-C并再次包装它.
此外,任何此类API都是完全异步的.这意味着在您收到通知时,实际的文件系统状态可能会有所不同.然后精确或准确的通知实际上没有用,并且仅用于标记脏标志.
我最终FSEvents为Swift 编写了一个包装器.这是我的工作,我希望这会有所帮助.
我修改了斯坦尼斯拉夫·斯米达(Stanislav Smida)的代码,使其可以与Xcode 8和Swift 3一起使用
class DirectoryObserver {
private let fileDescriptor: CInt
private let source: DispatchSourceProtocol
deinit {
self.source.cancel()
close(fileDescriptor)
}
init(URL: URL, block: @escaping ()->Void) {
self.fileDescriptor = open(URL.path, O_EVTONLY)
self.source = DispatchSource.makeFileSystemObjectSource(fileDescriptor: self.fileDescriptor, eventMask: .all, queue: DispatchQueue.global())
self.source.setEventHandler {
block()
}
self.source.resume()
}
}
Run Code Online (Sandbox Code Playgroud)
最简单的解决方案是使用Apple的DirectoryMonitor.swift https://developer.apple.com/library/mac/samplecode/Lister/Listings/ListerKit_DirectoryMonitor_swift.html
var dm = DirectoryMonitor(URL: AppDelegate.applicationDocumentsDirectory)
dm.delegate = self
dm.startMonitoring()
Run Code Online (Sandbox Code Playgroud)
您可以将 UKKQueue 添加到您的项目中。请参阅http://zathras.de/angelweb/sourcecode.htm,它很容易使用。UKKQueue 是用 Objective C 编写的,但您可以在 swift 中使用它
| 归档时间: |
|
| 查看次数: |
9093 次 |
| 最近记录: |