Я прислушиваюсь к Каталогу и дисковым изменениям в использовании проекта Какао 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]]);
}
}
Большое спасибо заранее.
У меня была та же проблема, и я думаю, что понял ее. Очевидно, kFSEventStreamCreateFlagWatchRoot
просто отключается при использовании FSEventStreamCreateRelativeToDevice
. Вы должны использовать FSEventStreamCreate
. Поскольку первая форма предпочтительнее, если вы полагаетесь на идентификаторы исторических событий, вам может потребоваться создать 2 потока. Также обратите внимание, что, похоже, вы не получите kEventFlagChangedRoot
, отправленный вам, если ваше приложение не запущено, поэтому вам нужно будет указать каталог при запуске.
Я думаю, что изменение имени громкости не учитывается как изменение файловой системы, сообщаемой 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);