如何将 kFSEventStreamEventFlagEventIdsWrapped 与 FSEvents 一起使用?
Posted
技术标签:
【中文标题】如何将 kFSEventStreamEventFlagEventIdsWrapped 与 FSEvents 一起使用?【英文标题】:How to use kFSEventStreamEventFlagEventIdsWrapped with FSEvents? 【发布时间】:2013-11-07 16:10:31 【问题描述】:我正在尝试了解如何将 kFSEventStreamEventFlagEventIdsWrapped
事件标志与 FSEvents
一起使用。
根据文档,当事件 id 计数器回绕时,标志会发送到已注册的实例,从而使之前的事件 id 过时。
现在让我们想象以下场景:
我在我的申请中注册了FSEvents
;
处理完FSEvents
(例如,我的应用程序退出)后,我会保存在处理事件时遇到的最后一个事件 ID,以便能够重播来自该 ID 的更改;
当我的应用程序未运行时,事件 id 计数器会回绕。
我的问题是:我应该如何知道周围的柜台? (因此需要我重新扫描整个目录结构。)
【问题讨论】:
【参考方案1】:我现在直接从 Apple 那里得到了答复。
场景一开始就错了。保存最后处理的事件 id 时,您还必须保存事件流的 UUID。事件 ID 仅对给定的事件流有效,由其 UUID 标识(请参阅FSEventsCopyUUIDForDevice()
)。
每当事件 id 计数器回绕时,都会生成一个新的事件流 UUID。因此,如果您在事件 id 计数器环绕后重新启动应用程序,您存储的最后一个事件 id 将不再有效,并且 您会知道它,因为事件流 UUID 将不一样.
如果您遇到kFSEventStreamEventFlagEventIdsWrapped
标志,这意味着计数器在您的应用打开时被环绕。但是,没有什么特别的事情要做。如果您想保存最后一个事件 ID,您应该确保获取新的事件流 UUID。
【讨论】:
【参考方案2】:编辑:
事件 ID 不换行。
原因如下:假设您的机器每毫秒生成 1 个文件系统事件。这意味着它将每年生成 ms_per_year=31536000000 个文件系统事件。因此,计数器绕到 64 位边界还需要 5 亿多年。
>>> ms_per_year = 1000*60*60*24*365
>>> d64 = 2**64
>>> d64/ms_per_year
584942417L
【讨论】:
我知道事件 ID非常不太可能换行;你不回答这个问题。我只是想了解如何完全使用FSEvents
API。 (另外,如果事件 ID 不换行,为什么要创建 kFSEventStreamEventFlagEventIdsWrapped
标志?)您在版本之前的回答中说过,我不应该将事件 ID 保存到磁盘。你愿意详细说明吗? (文档似乎不同意:FSEventStreamGetLatestEventId() -> […] Clients can store this value persistently as long as they also store the UUID for the device
)。感谢您的宝贵时间。
好吧,我认为包装标志在那里是因为一些苹果工程师并没有真正掌握 64 位整数的巨大空间。也许您可以保存事件 ID,但它可能会包装两次,而您的应用程序未运行,那么您会怎么做?我的意思是,真的,来吧,它只是不换行。只需在运行多年的计算机上打印出一些事件 ID,它们类似于 123_000_000。即使您找到了处理事件 ID 包装的方法……您将如何实际测试它?你确定苹果工程师真的测试过这个标志是否真的有效吗?如果是,他们怎么样?
事实上您可以保存事件 ID,但您还必须保存事件流 UUID,因为事件 ID 仅对给定的事件流有效。当计数器回绕时,事件流 UUID 会发生变化。有关更多信息,请参阅我接受的答案。
顺便说一句,Apple 可以通过手动将事件 ID 设置为 2**64-42 来非常轻松地测试包装;)我当然希望他们这样做了;这是基本的编码 101 来测试你编码的任何东西。
@Frizlab:仅当您尝试测试环绕时它才会环绕。实际上,它永远不会环绕(除非你相信 500000000 年后会有 OS X...)【参考方案3】:
如果设置了kFSEventStreamEventFlagEventIdsWrapped
,则表示 64 位事件 ID 计数器环绕。因此,先前发布的事件 ID 不再是 FSEventStreamCreate()
函数的 sinceWhen 参数的有效参数。[1]
下次您应该将kFSEventStreamEventIdSinceNow
用于FSEventStreamEventId
,并且您必须重新扫描所有目录。
【讨论】:
感谢您引用文档(没有引用它……),但您可以猜到我确实阅读了文档。问题是如果应用程序未启动时包裹,我如何知道应用程序启动时包裹的计数器? @Frizlab 如果文档中没有解决方案,那么您应该在 2000 EB 的存储空间上尝试 fsevent,并让我们知道如何使用此标志。 如果可以的话我会的! :D 同时,我直接问苹果,看看他们怎么说 :) 得到了 Apple 的答复 ;)以上是关于如何将 kFSEventStreamEventFlagEventIdsWrapped 与 FSEvents 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章