代码之家  ›  专栏  ›  技术社区  ›  Dave Martorana

从MDItemRef确定本地驱动器

  •  0
  • Dave Martorana  · 技术社区  · 16 年前

    基本前提是,我想忽略本地驱动器中的任何内容,只关注外部USB驱动器上的文件。

    谢谢!

    3 回复  |  直到 16 年前
        1
  •  4
  •   Dave DeLong    16 年前

    一个简单的建议:

    抓取项目的路径,查看其前缀是否为“/Volumes/”。如果是,那么它就在外部设备上。

    MDItemRef myItem = ...;
    NSString * itemPath = (NSString *)MDItemCopyAttribute(myItem, kMDItemPath);
    if ([itemPath hasPrefix:@"/Volumes/"]) {
      NSLog(@"Found external item");
    } else {
      NSLog(@"Found internal item");
    }
    [itemPath release];
    
        2
  •  4
  •   Darren    16 年前

    检查/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;   
    }
    
        3
  •  0
  •   Jablair    16 年前

    您是只查看非引导驱动器还是外部驱动器(大多数时候它们的意思是一样的,但在具有多个分区或多个内部驱动器的系统(Mac Pro)上可能会有所不同。

    如果您只需要非内部驱动器,可以查看If路径是否以可移动驱动器装载点为前缀。

    与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/derive“。

    推荐文章