MAC OS X:Как определить, чувствительна ли файловая система к регистру?

Я использовал statfs (2) системный вызов для получения многих характеристик файловой системы Mac OS X, но он не говорит мне, чувствительна ли файловая система к регистру или нет.

Мне нужна эта информация, поскольку приложение, которое я разрабатываю, будет перемещать много файлов, и я хочу обнаружить потенциальную потерю данных из-за файлов, перемещаемых из случая -чувствительный файловая система для случая -нечувствительный файловой системы.

может кто-нибудь предложите способ обнаружить это?

4 ответов


если вы уже используете stat(2), тогда вы можете легко использовать pathconf(2) С _PC_CASE_SENSITIVE селектор (результат 0 = case-insensitve,1 = регистр. Обратите внимание, что man-страница устарела, но _PC_CASE_SENSITIVE и _PC_CASE_PRESERVING поддерживаются. По соглашению, если файловая система не поддерживает _PC_CASE_SENSITIVE селектор тогда чувствителен к регистру.


я осмотрелся и не нашел API для этого. Есть две возможности, о которых я могу думать:--12-->

  • создание временного файла и попытка открыть его с другим шаблоном регистра, например, создание "a9999" и попытка открыть "A9999". Учитывая, что ни "a9999", ни "A9999" не были доступны в этом конкретном каталоге, файловая система чувствительна к регистру, если и только если не удается открыть "A9999".
  • под управлением diskutil(8) против файловая система. Он сообщает о чувствительных к регистру, нечувствительных файловых системах по-разному:Name: Mac OS Extended (Case-sensitive) и Name: Mac OS Extended (не журнальный).

С diskutil(8) может идентифицировать это, это может быть случай, когда эта информация доступна через некоторый API или системный вызов.


Edit: получается, что NSURL имеет набор методов, которые работают со свойствами файловой системы. В частности, -getResourceValue:forKey:error С ключомNSURLVolumeSupportsCaseSensitiveNamesKey скажет вам, является ли данный файловая система (представлена как NSURL экземпляр) поддерживает имена с учетом регистра.

следующий код для примера ее использования.

#include <Foundation/Foundation.h>

int main(int argc, char *argv[]) {
  NSAutoreleasePool *pool = [NSAutoreleasePool new];

  NSString *path = [NSString stringWithCString:argv[1] encoding:NSASCIIStringEncoding];
  NSURL *filesystem = [NSURL fileURLWithPath:path isDirectory:YES];

  NSNumber *caseSensitiveFS;
  BOOL hasCaseSensitiveResource;

  hasCaseSensitiveResource = [filesystem getResourceValue:&caseSensitiveFS
    forKey:NSURLVolumeSupportsCaseSensitiveNamesKey error:NULL];

  if (hasCaseSensitiveResource)
  {
    if ([caseSensitiveFS intValue] == 1)
    {
      NSLog(@"%s is a case sensitive filesystem", argv[1]);
    }
    else
    {
      NSLog(@"%s is a case insensitive filesystem", argv[1]);
    }
  }
  else
  {
    NSLog(@"can't query %s for case sensitiveness", argv[1]);
  }

  [pool drain];
  return 0;
}

выход пример:

./testcase /
/ is a case insensitive filesystem

./testcase /Volumes/Disk\ Image/
/Volumes/Disk Image/ is a case sensitive filesystem

./testcase nonono
can't query nonono for case sensitiveness

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


посмотрите здесь для некоторого кода, чтобы найти подтип HFS устройства:

http://www.opensource.apple.com/source/libfs/libfs-3/FSFormatName.c

процедура is_hfs вернет подтип hfs. Если подтип kHFSXSubType или kHFSXJSubType, то это устройство HFSX (с учетом регистра).