当我收到从 Spotlight 查询(在 obj-c 中)返回的 MDItemRef 项目列表时,我想知道是否有一种简单的方法可以确定它们是来自操作系统安装驱动器还是来自外部连接的 USB 驱动器。
基本前提是我想忽略本地驱动器中的任何内容,只关注外部 USB 驱动器上的文件。
谢谢!
当我收到从 Spotlight 查询(在 obj-c 中)返回的 MDItemRef 项目列表时,我想知道是否有一种简单的方法可以确定它们是来自操作系统安装驱动器还是来自外部连接的 USB 驱动器。
基本前提是我想忽略本地驱动器中的任何内容,只关注外部 USB 驱动器上的文件。
谢谢!
在 /Volumes 中检查路径的问题在于它还包括内部分区,例如 /Volumes/WINDOWS。此外,虽然很少见,但外部驱动器可以有 /Volumes 以外的挂载点
更正确的方法是使用FSGetVolumeParms()
获取GetVolParmsInfoBuffer
包含有关卷的信息的结构,例如bIsEjectable
, bIsRemovable
, bIsOnInternalBus
。
您可以使用以下方法从 FSRef 获取 FSVolumeRefNum FSGetCatalogInfo()
:
FSCatalogInfo info = {0};
OSErr status = FSGetCatalogInfo(&fsRef, kFSCatInfoVolume, &info, nil, nil, nil);
if (status == noErr)
{
_volumeRefNum = info.volume;
}
使用volumeRef,您可以获得音量参数:
FSGetVolumeParms(_volumeRefNum, &_params, sizeof(_params));
_params 是一个包含以下GetVolParmsInfoBuffer
信息的结构:
- (BOOL) isEjectable
{
return (_params.vMExtendedAttributes & (1 << bIsEjectable)) != 0;
}
- (BOOL) isRemovable
{
return (_params.vMExtendedAttributes & (1 << bIsRemovable)) != 0;
}
- (BOOL) isAutoMounted
{
return (_params.vMExtendedAttributes & (1 << bIsAutoMounted)) != 0;
}
- (BOOL) isExternal
{
return (_params.vMExtendedAttributes & (1 << bIsOnExternalBus)) != 0;
}
- (BOOL) isInternal
{
return (_params.vMExtendedAttributes & (1 << bIsOnInternalBus)) != 0;
}
Una sugerencía 简单:
抓取项目的路径并查看它是否以“/Volumes/”为前缀。如果是,那么它在外部设备上。
例子:
MDItemRef myItem = ...;
NSString * itemPath = (NSString *)MDItemCopyAttribute(myItem, kMDItemPath);
if ([itemPath hasPrefix:@"/Volumes/"]) {
NSLog(@"Found external item");
} else {
NSLog(@"Found internal item");
}
[itemPath release];
您是否只查看非引导驱动器或外部驱动器(大多数情况下它们的含义相同,但在具有多个分区或多个内部驱动器(Mac Pro)的系统上它们可能会有所不同。
如果您只想要非内部驱动器,您可以查看路径是否以可移动驱动器安装点为前缀。
类似于 Dave 的代码:
MDItemRef myItem = ...;
NSString * itemPath = (NSString *)MDItemCopyAttribute(myItem, kMDItemPath);
NSArray * removableVolumes = [[NSWorkspace sharedWorkspace] mountedRemovableMedia];
BOOL externalVolume = NO;
for (NSString *eachVolume in removableVolumes) {
if ([itemPath hasPrefix: eachVolume]) {
externalVolume = YES;
break;
}
}
上行 - 忽略内部驱动器(如果这就是你想要的)。
缺点 - 包括已安装的驱动器图像(在你的情况下,如果它们是 Spotlight 索引的,我想)。
这实际上需要一些工作 - 如果内部驱动器安装点与外部驱动器具有相同的前缀,它可能会返回误报 - 例如,内部驱动器安装在“/Volumes/drive_2”和外部驱动器“/Volumes/drive ”。