9

我正在使用FSEvents. 当根文件夹被重命名或删除时,我需要获取事件。所以,我kFSEventStreamCreateFlagWatchRoot在创建FSEventStream. 但即使我删除或重命名根文件夹,我也没有得到相应FSEventStreamEventFlags的 . 任何想法可能是什么问题。我正在监听 USB 安装设备的变化。我同时使用了FSEventStreamCreateFSEventStreamCreateRelativeToDevice。我注意到的一件事是,当我尝试FSEventStreamCreate创建时收到以下错误消息FSEventStream

( CarbonCore.framework) FSEventStreamCreate:: 尝试为( ; 不支持操作)添加 kqueuewatch_all_parents时出错
fd 7/Volumes/NO NAME

但是FSEventStreamCreateRelativeToDevice没有错误,但仍然没有进入kFSEventStreamEventFlagRootChanged事件标志。此外,在使用FSEventStreamCreateRelativeToDevice苹果创建时,如果我想收听根路径更改,请传递 emty string ""。但是我无法通过传递空字符串来监听根路径的变化。但是当我通过"/"它的工作。但即使是"/"我也没有得到任何适当的FSEventStreamEventFlags. 我在这里粘贴代码:

-(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]]); 
    }    
}

提前非常感谢。

4

2 回答 2

3

我认为卷名的变化不算作FSEvents报告的文件系统的变化。请记住,卷名本身并不真正作为文件系统条目存在。下面的那些/Volumes是由操作系统制作的。

相反,它由Disk Arbitration涵盖。

下面是一个简短的示例代码。一、定义回调

#import <DiskArbitration/DiskArbitration.h>
void callBack(DADiskRef disk,CFArrayRef keys,void *context )
{
    CFDictionaryRef dict=DADiskCopyDescription(disk);
    NSString*mountPoint=[(NSDictionary*)dict objectForKey:(NSString*)kDADiskDescriptionVolumePathKey];
    NSLog(@"disk at %@:",mountPoint);
    for(NSString*key in (NSArray*)keys){
    NSLog(@"key %@ changed: %@",key,[(NSDictionary*)dict objectForKey:key]);    
    }
    CFRelease(dict);
}

然后像这样安装处理程序

DASessionRef session=DASessionCreate(NULL);
DARegisterDiskDescriptionChangedCallback(session, NULL, NULL, callBack, NULL);
DASessionScheduleWithRunLoop(session, [[NSRunLoop currentRunLoop] getCFRunLoop], kCFRunLoopCommonModes);
于 2010-01-28T16:00:40.347 回答
3

我有同样的问题,我想我想通了。显然kFSEventStreamCreateFlagWatchRoot只是在使用FSEventStreamCreateRelativeToDevice. 你必须使用FSEventStreamCreate. 如果您依赖历史事件 ID,则前一种形式更可取,因此您可能需要创建 2 个流。另外,请注意,如果您的应用程序未运行,您似乎不会被kEventFlagChangedRoot发送给您,因此您需要在启动时统计目录。

于 2010-03-12T21:28:09.197 回答