4

我正在编写一个将数据保存到特定文件夹内的一组文本文件中的应用程序。当其他应用程序(如 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);
        }
    }
}
4

2 回答 2

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,
于 2017-05-09T11:06:34.430 回答
0

除了. 之外,尝试设置kFSEventStreamCreateFlagMarkSelf为标志。这对我有用。FSEventStreamCreatekFSEventStreamCreateFlagIgnoreSelf

我想,这会触发生成“自己的”标志,因此可以忽略它。请让我们知道,如果这也适用于您。

于 2016-05-03T21:23:54.387 回答