FileWatcher / FileListener
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
fileprivate let queue = DispatchQueue(label: "FileMonitorQueue", target: .main) | |
enum FileWatcherError: Error { | |
case directoryOpenFailed(Int32) | |
case directoryURLInvalid(URL) | |
} | |
final class FileWatcher { | |
let fsSource: DispatchSourceFileSystemObject | |
var readSource: DispatchSourceRead! | |
init(in directory: URL, filename: String, errorHandler: ((Error) -> Void)?) throws { | |
let fileDescriptor: Int32 = try directory.withUnsafeFileSystemRepresentation { path in | |
guard let path = path else { throw FileWatcherError.directoryURLInvalid(directory) } | |
let result = open(path, O_EVTONLY) | |
guard result >= 0 else { throw FileWatcherError.directoryOpenFailed(errno) } | |
return result | |
} | |
fsSource = DispatchSource.makeFileSystemObjectSource( | |
fileDescriptor: fileDescriptor, | |
eventMask: .write, | |
queue: queue | |
) | |
fsSource.setEventHandler { [unowned self] in | |
do { | |
let fileHandle = try FileHandle( | |
forReadingFrom: directory.appendingPathComponent(filename) | |
) | |
self.readSource = DispatchSource.makeReadSource(fileDescriptor: fileHandle.fileDescriptor, queue: queue) | |
self.readSource.setEventHandler { | |
fileHandle.readToEndOfFileInBackgroundAndNotify() | |
} | |
self.readSource.resume() | |
self.readSource.setCancelHandler { | |
fileHandle.closeFile() | |
} | |
} catch { | |
errorHandler?(error) | |
} | |
} | |
fsSource.setCancelHandler { | |
close(fileDescriptor) | |
} | |
fsSource.resume() | |
} | |
deinit { | |
fsSource.cancel() | |
} | |
} | |
final class FileListener { | |
init() { | |
NotificationCenter.default.addObserver( | |
self, | |
selector: #selector(handler), | |
name: .NSFileHandleReadToEndOfFileCompletion, | |
object: nil | |
) | |
} | |
@objc func handler() { | |
/* file is available for reading here */ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sid,
I solved it myself :)
I needed to change line 26 from:
to