То, как прислушаться к файловой системе, изменяет MAC - kFSEventStreamCreateFlagWatchRoot

Я прислушиваюсь к Каталогу и дисковым изменениям в использовании проекта Какао FSEvents. Я должен получить события, когда корневая папка переименована или удалена. Так, я передал kFSEventStreamCreateFlagWatchRoot при создании FSEventStream. Но даже если я удаляю или переименовываю корневую папку, я не становлюсь соответствующим FSEventStreamEventFlags. Какая-либо идея, какова могла возможно быть проблема. Я прислушиваюсь к изменениям в смонтированном устройстве USB. Я использовал обоих FSEventStreamCreate и FSEventStreamCreateRelativeToDevice. Одна вещь, которую я замечаю, состоит в том, когда я пробую FSEventStreamCreate Я получаю следующее сообщение об ошибке при создании FSEventStream:

(CarbonCore.framework) FSEventStreamCreate: watch_all_parents:
ошибка, пытающаяся добавить kqueue для fd 7 (/Volumes/NO NAME; Операция, не поддерживаемая)

Но с FSEventStreamCreateRelativeToDevice нет никаких ошибок, но все еще получения kFSEventStreamEventFlagRootChanged во флагах события. Кроме того, в то время как использование создания FSEventStreamCreateRelativeToDevice say's яблока, если я хочу послушать корневые изменения пути, передает пустую строку "". Но я не могу послушать корневые изменения пути путем передачи пустой строки. Но когда я передаю "/" работает. Но даже для "/" Я не получаю никого надлежащего 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]]); 
    }    
}

Большое спасибо заранее.

9
задан Anne 21 September 2012 в 21:21
поделиться

2 ответа

У меня была та же проблема, и я думаю, что понял ее. Очевидно, kFSEventStreamCreateFlagWatchRoot просто отключается при использовании FSEventStreamCreateRelativeToDevice . Вы должны использовать FSEventStreamCreate . Поскольку первая форма предпочтительнее, если вы полагаетесь на идентификаторы исторических событий, вам может потребоваться создать 2 потока. Также обратите внимание, что, похоже, вы не получите kEventFlagChangedRoot , отправленный вам, если ваше приложение не запущено, поэтому вам нужно будет указать каталог при запуске.

3
ответ дан 4 December 2019 в 23:39
поделиться

Я думаю, что изменение имени громкости не учитывается как изменение файловой системы, сообщаемой FSEvents. Помните, сам название тома на самом деле не существует в качестве записи файловой системы. Темы под / тома приготовлены ОС.

Это все покрыто арбитражом диска .

Следует короткий пробный код. Во-первых, определите обратный вызов

#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);
3
ответ дан 4 December 2019 в 23:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: