更新文件大小时,不会调用监视目录更改的 DispatchSource

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

我写了一个 UITableViewController 的子class,它列出了一组目录中的文件及其各自的大小。当这些目录中有任何更改时,它也会自行更新。 class 使用 DispatchSource 到 "watch" 目录。这是执行此操作的代码:

    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()
    }

这段代码基本上是给每个目录添加一个watcher,当观察到变化时调用updateFileList。它运行完美,我的文件列表几乎可以立即更新任何更改。问题是,当我将一个大文件复制到一个目录时, updateFileList 会立即被调用。因此,我的控制器将新文件的大小显示为 0 字节。但是在文件被完全复制后,updateFileList 而不是 被调用,因此文件的实际大小没有更新。我怎样才能更新文件大小?

当您将观察者添加到目录时,您观察的是目录本身,而不是目录中的文件。目录只是文件列表。当该列表发生变化(创建、删除或移入或移出文件)时,目录会发生变化,并且会调用您的观察者。对文件内容的更改不会修改目录。

要监视文件的更改,您必须为该文件添加一个监视程序。