我正在创建带有目录路径的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?
答案 0 :(得分:0)
在开始时获取设备根路径并记住它可能会更容易。
您可以将-[NSURL getResourceValue:forKey:error:]
与密钥NSURLVolumeURLKey
一起使用,以获取卷的根目录的NSURL
。
或者,如果愿意,可以在原始路径上调用statfs()
。它将在struct statfs
中填写有关文件系统的信息。 f_mntonname
是该结构的字段,它是文件系统的安装路径。
要回答最初的问题,您必须枚举已挂载的文件系统,并查找与设备ID匹配的文件系统。您可以使用-[NSFileManager mountedVolumeURLsIncludingResourceValuesForKeys:options:]
或getfsstat()
进行枚举。使用前者,您仍然需要执行statfs()
来获取设备ID。对于后者,struct statfs
直接返回。