xcode NSFileManager 监视目录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7867991/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NSFileManager watch directory
提问by Gavy
How would you monitor a directory with NSFileManager
?
你将如何监视目录NSFileManager
?
I would like to able to detect when a file is deleted/added in my documents directory while my app is running.
我希望能够在我的应用程序运行时检测文件何时被删除/添加到我的文档目录中。
采纳答案by djromero
Look Kernel Queues: An Alternative to File System Eventsin Apple documentation.
There is an example for iOSin AVPlayerDemo (look DirectoryWatcher
class).
查看内核队列:Apple 文档中文件系统事件的替代方案。在 AVPlayerDemo(外观类)中有一个适用于 iOS的示例DirectoryWatcher
。
Also, check Directory Monitorblog post.
另外,请查看目录监视器博客文章。
回答by John Stephen
Here's my own version of DirectoryWatcher written in Swift using GCD instead of Mach and using a closure instead of a delegate
这是我自己用 Swift 编写的 DirectoryWatcher 版本,使用 GCD 而不是 Mach 并使用闭包而不是委托
import Foundation
@objc public class DirectoryWatcher : NSObject {
override public init() {
super.init()
}
deinit {
stop()
}
public typealias Callback = (_ directoryWatcher: DirectoryWatcher) -> Void
@objc public convenience init(withPath path: String, callback: @escaping Callback) {
self.init()
if !watch(path: path, callback: callback) {
assert(false)
}
}
private var dirFD : Int32 = -1 {
didSet {
if oldValue != -1 {
close(oldValue)
}
}
}
private var dispatchSource : DispatchSourceFileSystemObject?
@objc public func watch(path: String, callback: @escaping Callback) -> Bool {
// Open the directory
dirFD = open(path, O_EVTONLY)
if dirFD < 0 {
return false
}
// Create and configure a DispatchSource to monitor it
let dispatchSource = DispatchSource.makeFileSystemObjectSource(fileDescriptor: dirFD, eventMask: .write, queue: DispatchQueue.main)
dispatchSource.setEventHandler {[unowned self] in
callback(self)
}
dispatchSource.setCancelHandler {[unowned self] in
self.dirFD = -1
}
self.dispatchSource = dispatchSource
// Start monitoring
dispatchSource.resume()
// Success
return true
}
@objc public func stop() {
// Leave if not monitoring
guard let dispatchSource = dispatchSource else {
return
}
// Don't listen to more events
dispatchSource.setEventHandler(handler: nil)
// Cancel the source (this will also close the directory)
dispatchSource.cancel()
self.dispatchSource = nil
}
}
Use it like Apple's DirectoryWatcher example, something like this:
像 Apple 的 DirectoryWatcher 示例一样使用它,如下所示:
let directoryWatcher = DirectoryWatcher(withPath: "/path/to/the/folder/you/want/to/monitor/", callback: {
print("the folder changed")
})
Destroying the object will stop watching, or you can stop it explicitly
销毁对象将停止观看,或者您可以明确地停止它
directoryWatcher.stop()
It should be compatible with Objective C they way it's written (untested). Using it would be like this:
它应该以它们的编写方式(未经测试)与目标 C 兼容。使用它会是这样的:
DirectoryWatcher *directoryWatcher = [DirectoryWatcher.alloc initWithPath: @"/path/to/the/folder/you/want/to/monitor/" callback: ^(DirectoryWatcher *directoryWatcher) {
NSLog(@"the folder changed")
}];
Stopping it is similar
停止它是相似的
[directoryWatcher stop];