【发布时间】:2011-12-13 15:46:02
【问题描述】:
您将如何使用NSFileManager 监控目录?
我希望能够在我的应用程序运行时检测何时在我的文档目录中删除/添加了文件。
【问题讨论】:
-
这个问题被标记为 iPhone。而且这些链接的答案在 iOS 中都不起作用。
标签: iphone ios xcode nsfilemanager
您将如何使用NSFileManager 监控目录?
我希望能够在我的应用程序运行时检测何时在我的文档目录中删除/添加了文件。
【问题讨论】:
标签: iphone ios xcode nsfilemanager
这是我自己用 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
}
}
像 Apple 的 DirectoryWatcher 示例一样使用它,如下所示:
let directoryWatcher = DirectoryWatcher(withPath: "/path/to/the/folder/you/want/to/monitor/", callback: {
print("the folder changed")
})
销毁对象会停止观看,也可以显式停止
directoryWatcher.stop()
它应该与 Objective C 的编写方式兼容(未经测试)。使用它会是这样的:
DirectoryWatcher *directoryWatcher = [DirectoryWatcher.alloc initWithPath: @"/path/to/the/folder/you/want/to/monitor/" callback: ^(DirectoryWatcher *directoryWatcher) {
NSLog(@"the folder changed")
}];
停止类似
[directoryWatcher stop];
【讨论】:
在 Apple 文档中查看内核队列:文件系统事件的替代方案。
AVPlayerDemo 中有一个iOS 示例(请看DirectoryWatcher 类)。
另外,请查看 Directory Monitor 博文。
【讨论】: