File-level filesystem change notification in Mac OS X
Asked Answered
F

4

31

I want my code to be notified when any file under (either directly or indirectly) a given directory is modified. By "modified", I mean I want my code to be notified whenever a file's contents are altered, it's renamed, or it's deleted; or if a new file is added. For my application, there can be thousands of files.

I looked as FSEvents, but its Technology Overview says, in part:

The important point to take away is that the granularity of notifications is at a directory level. It tells you only that something in the directory has changed, but does not tell you what changed.

It also says:

The file system events API is also not designed for finding out when a particular file changes. For such purposes, the kqueues mechanism is more appropriate.

However, in order to use kqueue on a given file, one has to open the file to obtain a file descriptor. It's impractical to manage thousands of file descriptors (and would probably exceed the maximum allowable number of open file descriptors anyway).

Curiously, under Windows, I can use the ReadDirectoryChangesW() function and it does precisely what I want.

So how can one do what I want under Mac OS X? Or, asked another way: how would one go about writing the equivalent of ReadDirectoryChangesW() for Mac OS X in user-space (and do so very efficiently)?

Fiberboard answered 20/11, 2009 at 17:52 Comment(0)
L
7

I haven't tried this myself, but it seems like FSEvents is able to provide file-level notifications as of 10.7 (Lion). From the description of FSEventStreamCreateFlags:

kFSEventStreamCreateFlagFileEvents

Request file-level notifications. Your stream will receive events about individual files in the hierarchy you're watching instead of only receiving directory level notifications. Use this flag with care as it will generate significantly more events than without it.

Available in OS X v10.7 and later.

Longinus answered 27/5, 2014 at 14:23 Comment(0)
U
8

EDIT: Not verified, but Konstantin indicates below that this code sample is obsolete as of 2012.

I don't believe there's a specific API for what you're looking for. Apple provides sample code for a similar problem called Watcher. It is not what you are looking for, but it is about the best you can do at this point. You have to take snapshots of the directory, and rescan it when you find out something changed. Modification time is the best thing to check of course, if you can trust modification time.

You are probably correct that trying to register for an unbounded number of kqueues would likely be unworkable.

Unstep answered 23/11, 2009 at 5:5 Comment(3)
I generally dislike Windows programming and much prefer Mac/Linux programming. It just seems bizarre that there's apparently at least 1 thing that's easier to do in Windows.Fiberboard
Oh, there are many things easier to do on Windows. Try talking SOAP using Cocoa. NSArray is nice, but sometimes a C#-style generic would be very welcome. Mac has nothing even close to ASP.NET (I'm looking at you, WebObjects). I love Cocoa; it's by far the best framework I've ever encountered. But anyone who thinks that everything is better for developers on Mac than on Windows hasn't developed very much on both. For stuff like this, we're all waiting for that holy grail of zfs, which might make this kind of stuff easier and faster. Someday... (Microsoft has its dreams of winfs too...)Unstep
The problem is that you are bunching Linux programming with Mac programming. This is very easy to do on Linux with inotifywait.Romeo
L
7

I haven't tried this myself, but it seems like FSEvents is able to provide file-level notifications as of 10.7 (Lion). From the description of FSEventStreamCreateFlags:

kFSEventStreamCreateFlagFileEvents

Request file-level notifications. Your stream will receive events about individual files in the hierarchy you're watching instead of only receiving directory level notifications. Use this flag with care as it will generate significantly more events than without it.

Available in OS X v10.7 and later.

Longinus answered 27/5, 2014 at 14:23 Comment(0)
N
2

The closest utility (that I know of) that matches your needs on Mac OS X is fslogger. See the link for a description, dmg and source code: OSXBook - fslogger

Nernst answered 2/9, 2011 at 3:48 Comment(0)
V
-2

You might want to check out man fs_usage, though it's not specific to a directory and requires root privileges.

Vatican answered 15/6, 2010 at 6:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.