FSEventStreamCreateRelativeToDevice:如何获取deviceID的根文件夹?

时间:2018-12-31 12:00:39

标签: objective-c device fsevents

我正在创建带有目录路径的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。我想我需要以某种方式找到设备ID的根路径,然后调用[NSURL fileURLWithPath:relativeToURL:]。 我的问题是:如何获取设备ID的根URL?

1 个答案:

答案 0 :(得分:0)

在开始时获取设备根路径并记住它可能会更容易。

您可以将-[NSURL getResourceValue:forKey:error:]与密钥NSURLVolumeURLKey一起使用,以获取卷的根目录的NSURL

或者,如果愿意,可以在原始路径上调用statfs()。它将在struct statfs中填写有关文件系统的信息。 f_mntonname是该结构的字段,它是文件系统的安装路径。

要回答最初的问题,您必须枚举已挂载的文件系统,并查找与设备ID匹配的文件系统。您可以使用-[NSFileManager mountedVolumeURLsIncludingResourceValuesForKeys:options:]getfsstat()进行枚举。使用前者,您仍然需要执行statfs()来获取设备ID。对于后者,struct statfs直接返回。