I've been playing with FSEvents
in a little application of mine to synchronize the content of my application with what's on the hard drive (basically, it's a little image viewer, and I want its content to update when the content of the HDD changes)
I create my stream using the kFSEventStreamCreateFlagFileEvents
flag, but I have a hard time figuring out how those events are generated by the OS (or the kernel, or whatever) And unfortunately, there is no documentation with the events generated with this flag ... It seems they are new to 10.7, and still not documented.
So, my main problem is "rename". When I'm doing a simple rename, 2 kFSEventStreamEventFlagItemRenamed events are sent to my callback. One contains the old file name, the second contains the new file name. Problem occurs when you are renaming a batch of files, those events might not be sequencial. For example, it the following case :
- "file1" -> "new_file_1"
- "file2" -> "new_file_2"
I might receive the events in this order :
- "renamed" / "file1"
- "renamed" / "file2"
- "renamed" / "new_file_1"
- "renamed" / "new_file_2"
And there doesn't seem to be any way of getting the id of the first rename event when you catch the second one ... So what I did is : when receiving a "renamed" event, I do a stat() with the file name. If the stat returns successfully, it means that it's the new file name. If not, it means it's the old one. I still have NO WAY to link both events, but at least I can work around by deleting the old files and adding the new ones.
So, I basically have 2 questions :
The first is: Am I totally blind, and not seeing the obvious way to correctly catch a "renamed" event through fsevents ?
The second i: I sometimes have a strange bug where instead of only 2 renamed events, 3 are sent ! So I get a file added twice ... I'm not sure if this is a bug, or if this comes from the fact I'm completely missusing the fsevent API with the kFSEventStreamCreateFlagFileEvents
flag ...
Any help is welcome, I'm completely out of ideas to fix this !
Since these events only deal with paths, you'll have to do some extra work to handle renames. One option is to track the inode numbers of the files you're interested in. So when you do that stat call, also note the inode number and see if it matches any files you're tracking.
Be aware, though, that the OS may reuse the inode number of a deleted file, so depending on them as unique identifiers isn't infallible.
You can get the file ID by creating an URL from the path, then calling:
NSString *fileID = nil;
[url getResourceValue:&fileID forKey:NSURLFileResourceIdentifierKey error:&error]; //NS_AVAILABLE(10_7, 5_0);
(This identifier is not persistent across system restarts)
来源:https://stackoverflow.com/questions/8314348/cocoa-fsevents-kfseventstreamcreateflagfileevents-flag-and-renamed-events