【问题标题】:FSEventStream - filter events generated from my own applicationFSEventStream - 过滤从我自己的应用程序生成的事件
【发布时间】:2014-04-10 07:31:44
【问题描述】:

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

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

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

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

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

我想要的是忽略自生成的文件系统事件。

这是我用来设置 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);
        }
    }
}

【问题讨论】:

  • 看起来没有这样的方法,以防你监听文件的变化。也许“忽略自我”仅适用于文件夹级别...

标签: cocoa fsevents


【解决方案1】:

除了kFSEventStreamCreateFlagIgnoreSelf 之外,尝试将kFSEventStreamCreateFlagMarkSelf 设置为FSEventStreamCreate 的标志。这对我有用。

我猜,这会触发生成“自己的”标志,因此可以忽略它。如果这也适合您,请告诉我们。

【讨论】:

    【解决方案2】:

    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,
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-26
      • 1970-01-01
      • 1970-01-01
      • 2014-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多