【发布时间】:2010-12-07 10:42:37
【问题描述】:
当我收到从 Spotlight 查询(在 obj-c 中)返回的 MDItemRef 项目列表时,我想知道是否有一种简单的方法可以确定它们是来自操作系统安装驱动器还是来自外部连接的 USB 驱动器。
基本前提是我想忽略本地驱动器中的任何内容,只关注外部 USB 驱动器上的文件。
谢谢!
【问题讨论】:
标签: objective-c usb-drive spotlight
当我收到从 Spotlight 查询(在 obj-c 中)返回的 MDItemRef 项目列表时,我想知道是否有一种简单的方法可以确定它们是来自操作系统安装驱动器还是来自外部连接的 USB 驱动器。
基本前提是我想忽略本地驱动器中的任何内容,只关注外部 USB 驱动器上的文件。
谢谢!
【问题讨论】:
标签: objective-c usb-drive spotlight
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];
【讨论】:
在 /Volumes 中检查路径的问题在于它还包括内部分区,例如 /Volumes/WINDOWS。此外,虽然很少见,但外部驱动器可以有 /Volumes 以外的挂载点
更正确的方法是使用FSGetVolumeParms()得到一个包含卷信息的GetVolParmsInfoBuffer结构,如bIsEjectable、bIsRemovable、bIsOnInternalBus。
您可以使用 FSGetCatalogInfo() 从 FSRef 获取 FSVolumeRefNum:
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;
}
【讨论】:
您是否只查看非启动驱动器或外部驱动器(大多数情况下它们的含义相同,但在具有多个分区或多个内部驱动器 (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”和外部驱动器“/卷/驱动器”。
【讨论】: