FSEventStream - 过滤从我自己的应用程序生成的事件

时间:2014-04-10 07:31:45

标签: cocoa fsevents

我正在编写一个应用程序,将数据保存到特定文件夹中的一组文本文件中。 当其他应用程序(如Dropbox或TextEdit)更改文件时,我会收到FSEventStream通知,因此我可以使用提供的新文本内容更新我的应用程序。

问题我的FSEventStream - 尽管我设置了kFSEventStreamCreateFlagIgnoreSelf标志 - 即使在我自己的应用程序中修改文件,我也会收到通知。

这带来了很多复杂性,因为在我保存文件并获得文件更改通知后,我必须重新检查文件。我们可以在这里谈论优化,但是我的数据结构是很多不必要的操作和磁盘使用。

问题是:如何将a)文件事件与其他应用程序分开b)使用我自己的应用程序生成的文件事件?

我认为可能有办法通过FSEventID获取processID(后者在回调函数中提供)。但是没有找到任何关于它的东西。看起来提供的EventID仅用于定义FileEvents链中的顺序。

我想要的是是忽略自生成的FileSystem事件。

以下是我用来设置FSEventStream的代码:

NSArray * pathArray = [NSArray arrayWithObject:_pathToObserve];

FSEventStreamContext context;
context.info = self;
context.version = 0;
context.retain = NULL;
context.release = NULL;
context.copyDescription = NULL;

_fsEventStream = FSEventStreamCreate(NULL,
                                     filesystemObserverCallback,
                                     &context,
                                     (CFArrayRef)pathArray,
                                     kFSEventStreamEventIdSinceNow,
                                     1.0,
                                     kFSEventStreamCreateFlagIgnoreSelf|kFSEventStreamCreateFlagFileEvents|kFSEventStreamCreateFlagUseCFTypes);

FSEventStreamScheduleWithRunLoop(_fsEventStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
FSEventStreamStart(_fsEventStream);

回调函数:

void filesystemObserverCallback(ConstFSEventStreamRef streamRef,
                                void * clientCallBackInfo,
                                size_t numEvents,
                                void * eventPaths,
                                const FSEventStreamEventFlags eventFlags[],
                                const FSEventStreamEventId eventIds[])
{

    NSArray * pathArray = (NSArray *)eventPaths;

    for (int i=0; i < numEvents; i++)
    {
        NSString * path = [pathArray objectAtIndex:i];
        FSEventStreamEventFlags flags = flagsArray[i];

        if (flags & kFSEventStreamEventFlagItemCreated ||
            flags & kFSEventStreamEventFlagItemRemoved ||
            flags & kFSEventStreamEventFlagItemRenamed ||
            flags & kFSEventStreamEventFlagItemFinderInfoMod ||
            flags & kFSEventStreamEventFlagItemChangeOwner ||
            flags & kFSEventStreamEventFlagItemXattrMod)
        {

            NSLog(@">> item has changed at path: %@", path);
        }
    }
}

2 个答案:

答案 0 :(得分:0)

kFSEventStreamCreateFlagMarkSelf外,请尝试将FSEventStreamCreate设为kFSEventStreamCreateFlagIgnoreSelf的标记。这对我有用。

我想,这会触发&#34;拥有&#34;标志正在生成,所以可以忽略它。如果这也适合您,请告诉我们。

答案 1 :(得分:0)

osxdirk的回答肯定会奏效。来自FSEvents.h:

  /*
   * Indicates the event was triggered by the current process.
   * (This flag is only ever set if you specified the MarkSelf flag when creating the stream.)
   */
  kFSEventStreamEventFlagOwnEvent __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) = 0x00080000,