Api MacOSX:如何确定文件系统是否区分大小写?
我使用系统调用获得了MacOSX文件系统的许多特性,但它没有告诉我文件系统是否区分大小写 我需要这些信息,因为我正在开发的应用程序将移动许多文件,我希望检测由于文件从区分大小写的文件系统移动到区分大小写的文件系统而导致的潜在数据丢失Api MacOSX:如何确定文件系统是否区分大小写?,api,macos,filesystems,case-sensitive,Api,Macos,Filesystems,Case Sensitive,我使用系统调用获得了MacOSX文件系统的许多特性,但它没有告诉我文件系统是否区分大小写 我需要这些信息,因为我正在开发的应用程序将移动许多文件,我希望检测由于文件从区分大小写的文件系统移动到区分大小写的文件系统而导致的潜在数据丢失 有人能提出一种检测方法吗?用大写字母创建一个临时文件,并用小写字母检查文件是否存在,如果测试失败,文件系统是区分大小写的。我已经四处查看了,还没有找到相关的API。我可以想到两种可能性: 创建临时文件并尝试使用不同的案例模式打开它,例如创建“a9999”并尝试打开
有人能提出一种检测方法吗?用大写字母创建一个临时文件,并用小写字母检查文件是否存在,如果测试失败,文件系统是区分大小写的。我已经四处查看了,还没有找到相关的API。我可以想到两种可能性:
- 创建临时文件并尝试使用不同的案例模式打开它,例如创建“a9999”并尝试打开“a9999”。考虑到“a9999”和“a9999”在该特定目录上都不可用,因此当且仅当打开“a9999”失败时,文件系统才区分大小写
- 对文件系统运行
。它以不同的方式报告区分大小写、不区分大小写的文件系统:diskutil(8)
与名称:Mac OS Extended(区分大小写)
(不记录)名称:Mac OS Extended
diskutil(8)
能够识别这一点,因此可能通过一些API或系统调用来获取此信息
Edit:事实证明,
NSURL
有一组处理文件系统属性的方法。特别是,-getResourceValue:forKey:error
的键为nsurlVolumesSupportsCaseSensitiveNamesKey
将告诉您给定的文件系统(表示为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;
}
在此处查找一些代码以查找设备的HFS子类型:
例行程序是_hfs将返回hfs子类型。如果子类型是kHFSXSubType或KHFSxJSSubType,则它是HFSX(区分大小写)设备。如果您已经在使用
stat(2)
,则可以轻松地使用\u PC\u区分大小写的
选择器(结果0
=不区分大小写,1
=区分大小写。请注意,手册页已过期,但\u PC\u区分大小写
和\u PC\u区分大小写
受支持。按照惯例,如果文件系统不支持\u PC\u区分大小写
选择器,则它区分大小写。我无法o在我的系统上找到libfs。看起来没有一个系统库导出FSFormatName.h中声明的函数。非常感谢。还有什么更通用的方法涵盖其他文件系统类型吗?@bavariable:我不是建议在可用的库中使用该例程。我是说用该代码作为示例,说明如何执行以下操作:至少,他需要这么做。@Ken不过,如果libfs可用就好了。无论如何,该代码使用了Mac OS 10.6上没有的头文件和函数,即getblk()
和getwrapper(),显然应该在<代码> <代码>中声明,在<代码> /Ur/LIB < /> >下,任何库都不可用。因为没有执行这些工作的代码< NSURL>代码>,我没有进一步研究。我应该提到我使用C++,而不是ObjuleC;有没有C/C++解决方案?实际上在想,这个MI。ght是最有用的解决方案-我没有理由不能在我的应用程序中使用它。@trojanfoe,据我所知。即使libfs不可用,您也可以尝试使用FSFormatName.c的源代码,正如Ken在回答中指出的那样。它看起来只是读取了几个块,而且,不管它值多少钱,它在我不太了解Objto-C,所以我不能从C++中调用上面的代码(我已经看了关于这个主题的问题,但是我需要引用ObjuleC对象来工作)…我不确定你的问题是什么。
函数转换为标准C函数,该函数接受装入点字符串作为其唯一参数,并返回一个涵盖三种情况(区分大小写、不区分大小写、查询失败)的整数。使用函数的定义构建一个对象文件,在头文件中声明,并将头文件包含为外部“C”在C++代码中,将对象文件与代码的其余部分链接。是的,这可能是可行的——虽然看起来有些粗糙:但是,它也是一个跨平台的解决方案:)表明这是不可靠的。
./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