FSEvents处理由其他操作系统更改的磁盘

时间:2012-09-02 21:23:35

标签: macos fsevents

我在FSEvents上看到奇怪的行为,我将驱动器安装在恢复模式下,并在重启时在我的流中获得零fsevents。 我做了以下事情:

  1. 定期开机
  2. 使用FSEventsGetCurrentEventId()
  3. 记录当前事件
  4. 以恢复模式启动并修改监视路径中的文件
  5. 重新启动系统
  6. 当发生这种情况时,我在使用fsevents API时根本没有任何事件。它在kFSEventStreamEventFlagHistoryDone哨兵中发送的唯一标志,即使我在常规操作系统上进行了其他更改。

    这个ars technica review似乎意味着当你在其他设备上挂载时,你应该得到kFSEventStreamEventFlagMustScanSubDirs标志,但我没有看到这种行为。以前有人遇到过这个吗?有没有更好的方法来检测和处理驱动器在操作系统关闭时安装在其他地方的情况?

    更新:我尝试从linux启动并修改文件系统。无论如何,我都没有得到0事件的同样奇怪的行为,但我也没有从我更改的目录或MustScanSubdirs标志中获取事件。

    更新2:在this thread中,接受的响应表明,当发生这种情况时,时间机器会在上述情况下检测到日志已过期。有人知道如何检测日志是否过时?可以使用此日期代替标记。

1 个答案:

答案 0 :(得分:2)

我认为您还需要在步骤#2中存储FSEvents数据库的UUID,并在步骤#4中检查它。

此行为为vaguely mentioned in Apple's documentation(强调添加):

  

注意:因为运行早期版本的OS X(或可能是其他操作系统)的计算机可以修改磁盘,所以您应该将事件列表视为建议而不是所有更改的明确列表。音量。 如果运行以前版本的OS X的计算机修改了磁盘,则会丢弃历史记录。

     

例如,备份软件应该定期执行任何卷的完整扫描,以确保没有任何变化通过裂缝。

注意关于被丢弃的历史日志的位,然后查看reference(强调添加):

  

FSEventStreamGetLatestEventId() - >最初,这将返回   因为当创建流时提供的值;之后,它   使用当前提到的编号最大的事件ID进行更新   在调用客户端的回调之前的一批事件。的客户端   只要它们还存储UUID,它就可以持久存储该值   对于设备(通过FSEventsCopyUUIDForDevice()获得)。客户可以   然后将此事件ID作为Since参数提供给   FSEventStreamCreateRelativeToDevice(),只要其UUID匹配即可   你存储了什么。这是因为FSEvents服务存储事件   在持久的每卷数据库中。在这方面,流   事件ID就像一个全局的系统范围的时钟,但没有任何关系   任何特定的时基。

     

FSEventsCopyUUIDForDevice() - >获取唯一标识的UUID   该卷的FSEvents数据库。 如果数据库被丢弃   然后它的替换将具有不同的UUID,以便客户端   能够检测到这种情况并避免尝试使用事件ID   他们存储为SinceWhen参数   FSEventStreamCreate ...()函数。

请注意,UUID是每个设备,因此如果您在目录树中安装了任何文件系统,则可能需要获取每个文件系统的UUID。

祝你好运!