Cocoa, FSEvents, kFSEventStreamCreateFlagFileEvents flag and “renamed” events

浪尽此生 提交于 2019-12-04 12:36:57

问题


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 :

  1. "file1" -> "new_file_1"
  2. "file2" -> "new_file_2"

I might receive the events in this order :

  1. "renamed" / "file1"
  2. "renamed" / "file2"
  3. "renamed" / "new_file_1"
  4. "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 !


回答1:


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.




回答2:


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)




回答3:


You need to use the flag kFSEventStreamCreateFlagUseExtendedData (available since OS X 10.13). A stream created with that flag will include the inode of the event file. That way you can detect "rename chains" that happened in a reported event batch.

P.S. macOS may reuse the inode of a deleted file for a newly created one, although if you process the events right away, the risk is negligible.



来源:https://stackoverflow.com/questions/8314348/cocoa-fsevents-kfseventstreamcreateflagfileevents-flag-and-renamed-events

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!