Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A DispatchSource watching for changes in directories is not called when file sizes are updated

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?

like image 925
mohak Avatar asked Jun 28 '17 10:06

mohak


1 Answers

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.

like image 122
Rob Napier Avatar answered Nov 12 '22 02:11

Rob Napier