如何监听文件系统更改MAC

如何监听文件系统更改MAC

本文介绍了如何监听文件系统更改MAC - kFSEventStreamCreateFlagWatchRoot的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 FSEvents 在Cocoa项目中监听目录和磁盘更改。我需要在重命名或删除根文件夹时获取事件。所以,在创建 FSEventStream 时,我通过了 kFSEventStreamCreateFlagWatchRoot 。但即使我删除或重命名根文件夹,我没有得到相应的 FSEventStreamEventFlags 。任何想法可能是这个问题。我正在监听USB安装设备的更改。我使用 FSEventStreamCreate FSEventStreamCreateRelativeToDevice 。我注意到的一个事情是,当我尝试与 FSEventStreamCreate 我得到以下错误消息,同时创建 FSEventStream

I am listening for Directory and disk changes in a Cocoa project using FSEvents. I need to get events when a root folder is renamed or deleted. So, I passed kFSEventStreamCreateFlagWatchRoot while creating the FSEventStream. But even if I delete or rename the root folder I am not getting corresponding FSEventStreamEventFlags. Any idea what could possibly be the issue. I am listening for changes in a USB mounted device. I used both FSEventStreamCreate and FSEventStreamCreateRelativeToDevice. One thing I notices is when I try with FSEventStreamCreate I get the following error message while creating FSEventStream:

但是 FSEventStreamCreateRelativeToDevice 没有错误,但仍然无法在事件标志中获得 kFSEventStreamEventFlagRootChanged 。另外,虽然创建使用 FSEventStreamCreateRelativeToDevice 苹果说如果我想监听根路径更改传递emty字符串。但我不能通过传递空字符串来监听根路径更改。但是当我通过/它工作。但是即使对于/我没有得到任何适当的 FSEventStreamEventFlags 。我在这里粘贴代码:

But with FSEventStreamCreateRelativeToDevice there are no errors but still not getting kFSEventStreamEventFlagRootChanged in event flags. Also, while creation using FSEventStreamCreateRelativeToDevice apple say's if I want to listen to root path changes pass emty string "". But I am not able to listen to root path changes by passing empty string. But when I pass "/" it works. But even for "/" I do not get any proper FSEventStreamEventFlags. I am pasting the code here:

-(void) subscribeFileSystemChanges:(NSString*) path
{
    PRINT_FUNCTION_BEGIN;

    // if already subscribed then unsubscribe
    if (stream)
    {
        FSEventStreamStop(stream);
        FSEventStreamInvalidate(stream); /* will remove from runloop */
        FSEventStreamRelease(stream);
    }

    FSEventStreamContext cntxt = {0};
    cntxt.info = self;

    CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void**)&path, 1, NULL);


    stream = FSEventStreamCreate(NULL, &feCallback, &cntxt,
                                 pathsToWatch, kFSEventStreamEventIdSinceNow, 1,
                                 kFSEventStreamCreateFlagWatchRoot );


    FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(),
                                     kCFRunLoopDefaultMode);

    FSEventStreamStart(stream);


}

回拨函数:

static void feCallback(ConstFSEventStreamRef streamRef, void* pClientCallBackInfo,
                       size_t numEvents, void* pEventPaths, const    FSEventStreamEventFlags eventFlags[],
                       const FSEventStreamEventId eventIds[])

{
char** ppPaths = (char**)pEventPaths; int i;

    for (i = 0; i < numEvents; i++)
    {
        NSLog(@"Event Flags %lu Event Id %llu", eventFlags[i], eventIds[i]);
        NSLog(@"Path changed: %@",
              [NSString stringWithUTF8String:ppPaths[i]]);
    }
}

提前多谢。

推荐答案

我有同样的问题,我想我想出来了。显然,当使用 FSEventStreamCreateRelativeToDevice 时, kFSEventStreamCreateFlagWatchRoot 您必须使用 FSEventStreamCreate 。由于如果您依赖于历史事件ID,则以前的形式是首选,您可能需要创建2个流。另外,请注意,如果您的应用程序未运行,您似乎没有收到 kEventFlagChangedRoot ,因此您需要在启动时统计目录。

I had the same problem and I think I figured it out. Apparently kFSEventStreamCreateFlagWatchRoot is just simply busted when using FSEventStreamCreateRelativeToDevice. You have to use FSEventStreamCreate. Since the former form is preferable if you're relying on historical event ids, you might need to create 2 streams. Also, note that it appears that you don't get kEventFlagChangedRoot sent to you if your app isn't running, so you'll need to stat the directory when you start up.

这篇关于如何监听文件系统更改MAC - kFSEventStreamCreateFlagWatchRoot的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 23:21