MAC OS X:如何确定文件系统是否区分大小写?

时间:2011-01-16 15:35:45

标签: api macos filesystems case-sensitive

我已经使用statfs(2)系统调用来获取Mac OS X文件系统的许多特性,但它并没有告诉我文件系统是否区分大小写。

我需要这些信息,因为我正在开发的应用程序将移动许多文件,我想检测由于文件从案例 - 敏感文件系统移动到案例而导致的潜在数据丢失 - 不敏感文件系统。

有人能提出一种检测方法吗?

4 个答案:

答案 0 :(得分:9)

我环顾四周,但没有为此找到API。我能想到两种可能性:

  • 创建一个临时文件并尝试使用不同的案例模式打开它,例如创建“a9999”并尝试打开“A9999”。考虑到该特定目录上既没有“a9999”也没有“A9999”,当且仅当打开“A9999”失败时,文件系统才区分大小写。
  • 对文件系统运行diskutil(8)。它以不同的方式报告区分大小写的不敏感文件系统:Name: Mac OS Extended (Case-sensitive)Name: Mac OS Extended(不是日记)。

由于diskutil(8)能够识别出来,因此可能会通过某些API或系统调用获取此信息。


编辑:事实证明NSURL有一组适用于文件系统属性的方法。特别是,密钥为-getResourceValue:forKey:error的{​​{1}}将告诉您给定的文件系统(表示为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;
}

答案 1 :(得分:9)

如果您已使用stat(2),那么您可以轻松地将pathconf(2)_PC_CASE_SENSITIVE选择器一起使用(结果0 =不区分大小写,1 =区分大小写。请注意,手册页已过期,但支持_PC_CASE_SENSITIVE_PC_CASE_PRESERVING。按照惯例,如果文件系统不支持_PC_CASE_SENSITIVE选择器,那么它区分大小写。

答案 2 :(得分:6)

使用大写字母创建临时文件,并使用小写字母检查文件是否存在,如果测试失败则文件系统 区分大小写。

答案 3 :(得分:1)

在这里查找一些代码来查找设备的HFS子类型:

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

例程is_hfs将返回hfs子类型。如果子类型是kHFSXSubType或kHFSXJSubType,那么它是一个HFSX(区分大小写)设备。