Problems monitoring a file for metadata changes

I need to monitor a file for when its metadata changes.

I'm using the following code I found.

Code Block
final class FileMonitor
{
  let url: URL
  var fileHandle: FileHandle?
  var source: DispatchSourceFileSystemObject?
  var didReceiveChanges: (() -> Void)?
  func process(event: DispatchSource.FileSystemEvent)
  {
    print(String(describing: event))
    didReceiveChanges?()
  }
  func eventHandler()
  {
    let event = self.source!.data
    process(event: event)
    createDispatchSource()
  }
  func createDispatchSource()
  {
    self.fileHandle = try? FileHandle(forReadingFrom: url)
    source = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileHandle!.fileDescriptor, eventMask: [.attrib], queue: DispatchQueue.main)
    source!.setEventHandler(handler: eventHandler)
    source!.setCancelHandler
    {
      self.fileHandle!.closeFile()
    }
    source!.resume()
  }
  init(url: URL) throws
  {
    self.url = url
    createDispatchSource()
  }
  deinit
  {
    source!.cancel()
  }
}

The problem is that I am getting nearly 7,000 notifications every time a change is detected, which is causing the CPU to get rather warm.

This subject seems to be very poorly documented and after days searching, I don't seem to be able to make things any better.

Any ideas please?

Joanna

Replies

I'm not familiar with this. But why do you createDispatchSource each time an event is processed ?

Code Block
func eventHandler() {
let event = self.source!.data
process(event: event)
createDispatchSource()
}


Because it crashes if you don't. Something to do with unbalanced calls to resume and suspend apparently.

Because it crashes if you don't.

Yeah, that suggests deeper problems. Rather than debug those I’m going to suggest that you start with some code that works, namely the DirectoryMonitor class from this post.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"