Определить локальный диск из MDItemRef

Когда я получаю список элементов MDItemRef, возвращенных из запроса Spotlight (в obj-c), мне было интересно, есть ли простой способ определить, поступают ли они с установочного диска ОС или с внешнего USB-накопителя.

Основная предпосылка заключается в том, что я хочу игнорировать что-либо с локального диска и следить за файлами только на внешних USB-накопителях.

Спасибо!


person Dave Martorana    schedule 16.10.2009    source источник


Ответы (3)


Una sugerencía simple:

Возьмите путь к элементу и посмотрите, есть ли у него префикс «/Volumes/». Если да, то на внешнем устройстве.

Пример:

MDItemRef myItem = ...;
NSString * itemPath = (NSString *)MDItemCopyAttribute(myItem, kMDItemPath);
if ([itemPath hasPrefix:@"/Volumes/"]) {
  NSLog(@"Found external item");
} else {
  NSLog(@"Found internal item");
}
[itemPath release];
person Dave DeLong    schedule 16.10.2009

Проблема с проверкой путей в /Volumes заключается в том, что она также включает внутренние разделы, такие как /Volumes/WINDOWS. Кроме того, хотя и редко, внешние диски могут иметь точки монтирования, отличные от /Volumes.

Правильнее использовать FSGetVolumeParms() для получения структуры GetVolParmsInfoBuffer, содержащей информацию о томе, например bIsEjectable, bIsRemovable, bIsOnInternalBus.

Вы можете получить FSVolumeRefNum из FSRef, используя 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;   
}
person Darren    schedule 19.10.2009

Вы ищете только незагрузочные диски или внешние диски (в большинстве случаев они означают одно и то же, но они могут отличаться в системе с несколькими разделами или несколькими внутренними дисками (Mac Pro).

Если вам нужны только не внутренние диски, вы можете посмотреть, есть ли у пути префикс с точкой подключения съемного диска.

Подобно коду Дэйва:

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». ".

person Jablair    schedule 19.10.2009