I wrote a sub-class of UITableViewController that lists the files in a group of directories along with their respective sizes. It also updates itself when there are any changes in those directories. The class uses DispatchSource
to "watch" the directories. Here's the code that does that:
for dir in directories {
let fd = dir.withUnsafeFileSystemRepresentation { (filenamePointer) -> Int32 in
// vfw_open is a wrapper function for open()
return vfw_open(filenamePointer, O_EVTONLY)
}
guard fd != 0 else {
return
}
let watcher = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fd,
eventMask: DispatchSource.FileSystemEvent.write,
queue: DispatchQueue.global(qos: .utility))
watcher.setEventHandler { [weak self] in
DispatchQueue.main.async {
self?.updateFileList()
}
}
watcher.setCancelHandler() {
close(fd)
}
watcher.resume()
}
This piece of code basically adds a watcher to each directory and calls updateFileList
when changes are observed. It works perfectly and my file list is updated almost instantly with any changes. The problem is, when I copy a large file to a directory, updateFileList
is called immediately. So, my controller shows the size of the new file as 0 bytes. But after the file is completely copied, updateFileList
is not called and hence the file's actual size is not updated. How can I get the file size to get updated?
When you add a watcher to a directory, you are watching the directory itself, not the files in the directory. A directory is just a list of files. When that list changes (a file is created, deleted, or moved in or out), then the directory changes, and your watcher is called. Changes to the files' contents do not modify the directory.
To watch for changes to a file, you must add a watcher for the file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With