问题
I have used the statfs(2) system call to get many characteristics of a Mac OS X filesystem, but it doesn't tell me if the filesystem is case-sensitive or not.
I need this information as the application I am developing will be moving many files around and I want to detect potential loss of data due to files being moved from a case-sensitive filesystem to a case-insensitive filesystem.
Can anyone suggest a way of detecting this?
回答1:
If you're already using stat(2), then you can easily use pathconf(2) with the _PC_CASE_SENSITIVE selector (result 0 = case-insensitve, 1 = case-sensitive. Note that the man page is out of date, but the _PC_CASE_SENSITIVE and _PC_CASE_PRESERVING are supported. By convention, if a file system doesn't support _PC_CASE_SENSITIVE selector then it is case-sensitive.
回答2:
I’ve looked around and haven’t found an API for that. There are two possibilities I can think of:
- Creating a temporary file and trying to open it with a different case pattern, e.g. creating "a9999" and trying to open "A9999". Considering that neither "a9999" nor "A9999" were available on that particular directory, the filesystem is case-sensitive if and only if opening "A9999" fails.
- Running
diskutil(8)against the filesystem. It reports case-sensitive, -insensitive file systems differently:Name: Mac OS Extended (Case-sensitive)vs.Name: Mac OS Extended(not journaled).
Since diskutil(8) is able to identify that, it could be the case that this information is available via some API or system call.
Edit: It turns out that NSURL has a set of methods that work on file system properties. In particular, -getResourceValue:forKey:error with the key being NSURLVolumeSupportsCaseSensitiveNamesKey will tell you whether a given filesystem (represented as an NSURL instance) supports case sensitive names.
See the following code for an example of its use.
#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;
}
Output example:
./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
回答3:
Create a temporary file with uppercase letters and check if the file exists using lowercase letters, if the test fails the file system is case-sensitive.
回答4:
Look here for some code to find the HFS subtype of a device:
http://www.opensource.apple.com/source/libfs/libfs-3/FSFormatName.c
The routine is_hfs will return the hfs subtype. If the subtype is kHFSXSubType or kHFSXJSubType, then it's an HFSX (case sensitive) device.
来源:https://stackoverflow.com/questions/4706215/mac-os-x-how-to-determine-if-filesystem-is-case-sensitive