12

I want to monitor a directory (of thousands of files, with about 5 levels of sub directories) for when files are changed. I know I can use the FSEvents API to monitor a directory for when files change inside that directory, but I can't seem to figure out how to determine which file(s) changed. This reference suggests I build a binary tree and traverse the tree each time an event is triggered, is that the best way to determine which files were changed? If not, what are some better alternatives?

Is it better to recursively scan the directory and attach kqueue to every file? I'm not sure how well that would work on thousands of files?

v0idless
  • 948
  • 2
  • 11
  • 24

2 Answers2

8

I've used UKKQueue before with mixed results.

I've recently become aware of a better solution, but I haven't tried this. If you only need to target Lion, I think that the new best-practice way to do this is to use an NSFileCoordinator. You implement the methods of NSFilePresenter to indicate which directory you're interested in (the presentedItemURL property) and the system will notify you when a sub item moves/changes/is deleted (via methods like presentedSubitemDidChangeAtURL:)

I'd love to hear how that works out if you do go that route.

Jesse Rusak
  • 56,530
  • 12
  • 101
  • 102
  • 1
    Jesse, have you tried using NSFileCoordinator/NSFilePresenter to implement monitoring of some folder so far? I wasn't able to make this solution work—it simply doesn't notify me about any events. – Daniel O'Hara Sep 09 '12 at 22:26
  • @DaveNewman NSFileCoordinator only works if the program that's making the changes is using it as well. (i.e. it's an opt-in API) Most Cocoa programs will do this; are the changes you're seeing being made by a lower-level API, perhaps? – Jesse Rusak Sep 10 '12 at 12:31
  • 1
    I don't understand. For example, I've created a file presenter for my folder, say, '/Users/Dave/MyFolder'. Now when I drop files into this directory (drag&drop), only `presentedSubitemDidChangeAtURL:` method is being called by system, but not `presentedSubitemDidAppearAtURL:`. It also doesn't call `accommodatePresentedSubitemDeletionAtURL` when I delete some files in Finder. Did I miss anything? – Daniel O'Hara Sep 10 '12 at 19:59
  • @DaveNewman I'm not sure. At least you're getting callbacks, though. Perhaps you could start a new question about it with some more details about how you're setting up the monitoring to see if anyone knows what's going on. – Jesse Rusak Sep 11 '12 at 00:31
  • 1
    @DaveNewman I am facing [exactly the same problem](http://stackoverflow.com/questions/12389726/nsfilepresenter-presentedsubitemdidappearaturl-method-never-gets-called) – Konstantin Pavlikhin Sep 12 '12 at 13:54
  • As usual with Finder, "deleting" is actually "moving to trash" and "creating a file (atomically)" equals moving a buffered file to the destination. So you often only get a small subset of possible events and have to figure out what was going on in hindsight using context information. – ctietze Mar 01 '17 at 09:58
6

If you create your stream using kFSEventStreamCreateFlagFileEvents then you will get events for the changes to each file rather than just a notification of the change to the watched directory. Unfortunately this is only available in OSX 10.7 and later.

hvanbrug
  • 1,291
  • 2
  • 12
  • 25