gpt4 book ai didi

c++ - 如何解决 FSEventStream 中损坏的事件压缩

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:43:46 24 4
gpt4 key购买 nike

我们的 C++ 应用程序使用 FSEventStream 以文件级粒度监视文件系统(使用 kFSEventStreamCreateFlagFileEvents 标志创建流),每个卷一个监听器。但是,Apple FSEvent API 中似乎存在一些错误/错误功能,这源于它们在将事件发送给我们之前如何从流中压缩(删除重复)事件:

  1. 次要,但很烦人:当使用以前的事件 ID 作为起点启动流时(为了捕获 self 们上次监视以来对文件系统的更改),提供的事件顺序是与我们在事件发生时监听事件所得到的不同,因为事件不是按 eventId 顺序到达,而是按文件名按字母数字顺序排序。我们通过在处理集合之前将所有历史事件累积在一个 id 排序列表中来解决这个问题。

  2. 主要:如果重命名事件发生得足够快,回调函数中提供给我们的实际事件并不代表文件系统上实际发生的事情。考虑我们交换目录名称的测试用例:

    一个。更改文件

    将其父目录重命名为 _temp

    将另一个目录重命名为以前父目录的名称

    将 _temp 重命名为步骤 c 中的目录。

如果我们在每个步骤之间放置 50 毫秒的延迟(本质上,任何保证给定事件不会与另一个事件在同一回调中的延迟),我们就会得到正确的事件序列(重命名显示作为事件对):

fsEventsCallback: Received FSEvents callback with 1 events:
fsEventsCallback: ID=34303406 PATH= /Users/stebro/swaptest/subdir1/file_1.txt FLAGS=kFSEventStreamEventFlagItemInodeMetaMod, kFSEventStreamEventFlagItemIsFile, kFSEventStreamEventFlagItemModified
fsEventsCallback: Received FSEvents callback with 2 events:
fsEventsCallback: ID=34303436 PATH= /Users/stebro/swaptest/subdir1 FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: ID=34303437 PATH= /Users/stebro/swaptest/subdir1_temp FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: Received FSEvents callback with 2 events:
fsEventsCallback: ID=34303620 PATH= /Users/stebro/swaptest/subdir2 FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: ID=34303621 PATH= /Users/stebro/swaptest/subdir1 FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: Received FSEvents callback with 2 events:
fsEventsCallback: ID=34303741 PATH= /Users/stebro/swaptest/subdir1_temp FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: ID=34303742 PATH= /Users/stebro/swaptest/subdir2 FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed

然而,在没有延迟的情况下(或者延迟足够小以至于多个重命名事件将在同一个回调调用中到达),操作系统似乎正在使用删除它认为是冗余事件的“优势”,结果在这个困惑中:

fsEventsCallback: Received FSEvents callback with 4 events:
fsEventsCallback: ID=34251572 PATH= /Users/stebro/swaptest/subdir1/file_1.txt FLAGS=kFSEventStreamEventFlagItemInodeMetaMod, kFSEventStreamEventFlagItemIsFile, kFSEventStreamEventFlagItemModified
fsEventsCallback: ID=34251580 PATH= /Users/stebro/swaptest/subdir1 FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: ID=34251583 PATH= /Users/stebro/swaptest/subdir1_temp FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: ID=34251584 PATH= /Users/stebro/swaptest/subdir2 FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed

我们可以做些什么来抑制这种压缩?我们正在使用此调用创建流:

FSEventStreamCreateRelativeToDevice(kCFAllocatorDefault,
&fsEventsCallback,
&context,
device,
reinterpret_cast<CFArrayRef>(_monitoredPaths),
lastEventId,
0, // Latency - problem exists with values of 1, 0.1 and 3 as well
kFSEventStreamCreateFlagFileEvents | kFSEventStreamCreateFlagNoDefer);

最佳答案

过度激进的事件折叠的解决方案可以使用 kFSEventStreamCreateFlagUseExtendedData(自 OS X 10.13 起可用)。使用该标志创建的流将包含事件文件的 inode。这样您就可以检测报告的事件批处理中发生的“重命名链”。

附言我在我的文件监视器中尝试了你的场景;事件顺序是正确的。

关于c++ - 如何解决 FSEventStream 中损坏的事件压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43638230/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com