FSEventStreamCreateRelativeToDevice: Как получить корневую папку для deviceID? - PullRequest
0 голосов
/ 31 декабря 2018

Я создаю поток FSEvents с путем к каталогу:

- (BOOL) registerFSEventsObserverForURL:(NSURL*)url error:(NSError **)error
{
    BOOL succeeded = YES;
    FSEventStreamContext context;
    context.version = 0;
    context.info = (__bridge void*) self;
    context.retain = NULL;
    context.release = NULL;
    context.copyDescription = NULL;

    NSString* path = [url path];

    dev_t device = [[self class] deviceIDForPath:path];

    NSArray* pathArray = [NSArray arrayWithObject:path];
    FSEventStreamRef stream = FSEventStreamCreateRelativeToDevice(NULL, &FSEventCallback,
                                                                  &context,
                                                                  device,
                                                                  (__bridge CFArrayRef)pathArray,
                                                                  kFSEventStreamEventIdSinceNow,
                                                                  1.0,
                                                                  0);
// ...

}

+ (dev_t)deviceIDForPath:(NSString*)path {
    struct stat statbuf;
    int result = stat([path fileSystemRepresentation], &statbuf);
    if (result == -1) {
        printf ("error with stat.  %d\n", errno);
        return EXIT_FAILURE;
    }
    dev_t device = statbuf.st_dev;
    return device;
}

static void FSEventCallback(ConstFSEventStreamRef inStreamRef, 
                            void* inClientCallBackInfo, 
                            size_t inNumEvents, 
                            void* inEventPaths, 
                            const FSEventStreamEventFlags inEventFlags[], 
                            const FSEventStreamEventId inEventIds[])
{
        dev_t device = FSEventStreamGetDeviceBeingWatched(inStreamRef);
        for (int i=0; i<inNumEvents; i++)
        {
           NSString* path = ((__bridge NSArray*)inEventPaths)[i];
           NSURL* url = [NSURL fileURLWithPath: path]; // Here I'm getting a non valid URL.
        }
}

Так, например, если url равен 'file:///Users/user1/Pictures', когда я получаю обратный вызов, путь такой же, как и ожидалось: 'Users/user1/Pictures' но я нене знаю, как получить URL-адрес файла по этому пути.Я думаю, что мне нужно как-то найти корневой путь для идентификатора устройства, а затем вызвать [NSURL fileURLWithPath:relativeToURL:].Мой вопрос: как мне получить корневой URL для идентификатора устройства?

1 Ответ

0 голосов
/ 31 декабря 2018

Вероятно, проще вначале получить корневой путь устройства и запомнить его.

Вы можете использовать -[NSURL getResourceValue:forKey:error:] с ключом NSURLVolumeURLKey, чтобы получить NSURL для корневого каталога тома.

Или, если хотите, вы можете позвонить statfs() по первоначальному пути.Он заполнит struct statfs информацией о файловой системе.В число полей этой структуры входит f_mntonname - путь, по которому монтируется файловая система.

Чтобы ответить на исходный вопрос, вам нужно будет перечислить смонтированные файловые системы и найти того, кто является устройством.ID совпадает.Вы можете использовать -[NSFileManager mountedVolumeURLsIncludingResourceValuesForKeys:options:] или getfsstat() для перечисления.В первом случае вам все равно нужно будет сделать statfs(), чтобы получить идентификатор устройства.С последним, struct statfs возвращаются напрямую.

...