Cocoa、FSEvents、kFSEventStreamCreateFlagFileEvents标志和;更名为;事件

Cocoa、FSEvents、kFSEventStreamCreateFlagFileEvents标志和;更名为;事件,cocoa,fsevents,Cocoa,Fsevents,我一直在我的一个小应用程序中玩FSEvents,以使我的应用程序的内容与硬盘上的内容同步(基本上,它是一个小图像查看器,我希望它的内容在HDD内容更改时更新) 我使用kFSEventStreamCreateFlagFileEvents标志创建流,但我很难弄清楚这些事件是如何由操作系统(或内核,或其他)生成的,不幸的是,没有使用此标志生成事件的文档。。。它们似乎是10.7的新版本,而且还没有文档记录 所以,我的主要问题是“重命名”。当我进行简单重命名时,2个KfseventStreamEventF

我一直在我的一个小应用程序中玩
FSEvents
,以使我的应用程序的内容与硬盘上的内容同步(基本上,它是一个小图像查看器,我希望它的内容在HDD内容更改时更新)

我使用
kFSEventStreamCreateFlagFileEvents
标志创建流,但我很难弄清楚这些事件是如何由操作系统(或内核,或其他)生成的,不幸的是,没有使用此标志生成事件的文档。。。它们似乎是10.7的新版本,而且还没有文档记录

所以,我的主要问题是“重命名”。当我进行简单重命名时,2个KfseventStreamEventFlagItemRename事件被发送到我的回调。一个包含旧文件名,第二个包含新文件名。重命名一批文件时出现问题,这些事件可能不是连续的。例如,它适用于以下情况:

  • “文件1”->“新建文件1”
  • “文件2”->“新建文件2”
  • 我可能会按以下顺序接收事件:

  • 已重命名“/“文件1”
  • 已重命名“/“文件2”
  • “重命名”/“新文件\u 1”
  • “重命名”/“新建文件2”
  • 当您捕获第二个重命名事件时,似乎没有任何方法可以获取第一个重命名事件的id。。。所以我所做的是:当接收到一个“重命名”事件时,我用文件名执行一个stat()。如果stat成功返回,则表示它是新文件名。如果不是,就意味着它是旧的。我仍然无法链接这两个事件,但至少我可以通过删除旧文件并添加新文件来解决问题

    所以,我基本上有两个问题:

    第一个问题是:我是否完全失明,看不到通过fsevents正确捕捉“重命名”事件的明显方式

    第二个i:我有时会遇到一个奇怪的bug,它不是只发送2个重命名事件,而是发送3个!所以我得到一个文件添加了两次。。。我不确定这是否是一个bug,或者这是因为我完全错误地将fsevent API与
    kFSEventStreamCreateFlagFileEvents
    标志一起使用


    欢迎任何帮助,我完全没有办法解决这个问题

    因为这些事件只处理路径,所以您必须做一些额外的工作来处理重命名。一个选项是跟踪您感兴趣的文件的inode编号。因此,当您进行stat调用时,还要注意inode编号,看看它是否与您正在跟踪的任何文件匹配


    不过,请注意,操作系统可能会重用已删除文件的inode编号,因此将其视为唯一标识符并非绝对正确。

    您可以通过从路径创建URL,然后调用:

    NSString *fileID = nil;
    
    [url getResourceValue:&fileID forKey:NSURLFileResourceIdentifierKey error:&error]; //NS_AVAILABLE(10_7, 5_0);
    

    (此标识符不会在系统重新启动时保持不变)

    您需要使用标志
    kFSEventStreamCreateFlagUseExtendedData
    (从OS X 10.13开始提供)。使用该标志创建的流将包括事件文件的inode。这样,您就可以检测报告的事件批中发生的“重命名链”

    p.S.macOS可能会将已删除文件的inode重新用于新创建的文件,尽管如果您立即处理事件,风险可以忽略不计