How can I standardize a path name?
How can I standardize a path name?
- Subject: How can I standardize a path name?
- From: Doug Simons <email@hidden>
- Date: Thu, 24 Jan 2002 14:26:21 -0700
Hello,
I'm trying to find a way to get a full standardized path name for a
file. The difficulty is related to HFS+ and Apple's file extension
hiding mechanism.
Here's a scenario: I get a file name (let's say it is "test.st") and
want to know if I have that file open already (I have a list of names of
files that are open). I standardize the path something like this:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *filePath = @"test.st"; // for illustration purposes
if (![filePath isAbsolutePath]) {
filePath = [[fileManager currentDirectoryPath]
stringByAppendingPathComponent: filePath];
}
filePath = [filePath stringByStandardizingPath];
Everything is great up to this point, with filePath being something like
"/Users/me/test.st"
HOWEVER, let's say the actual name of the file is "/Users/me/TEST.st".
HFS+ will allow me to access the file using either the upper- or
lower-case version of the name, but I need a way to know how it is
actually stored on the disk, so I don't open it twice (and also so that
I can present the name to the user the way it appears in the file
system).
So, I came across a nifty method in NSFileManager called
displayNameAtPath: which appears to solve the problem. That method
"Returns the name of the file or directory at path in a form appropriate
for presentation to the user." Initial testing showed that it returned
the name of the file only (without the directory) using the case as
stored in the file system.
So I added the following to my code:
(assume directory and displayName are declared as NSStrings)
directory = [filePath stringByDeletingLastPathComponent]; //
"/User/me/"
displayName = [fileManager displayNameAtPath:filePath]; // "TEST.st"
filePath = [directory stringByAppendingPathComponent:displayName];
Okay (whew!), now I've got my standardized, path. Right?
Well, almost, EXCEPT...
It turns out that displayNameAtPath: also checks whether the user has
specified that the file extension should be hidden for that file! If
so, instead of returning "TEST.st", it returns "TEST" (which is, of
course, perfect for displaying to the user, but not what I want!).
So, does anyone know a good, straightforward method of standardizing a
file path that will distinguish between "test", "TEST", "test.st", and
"TEST.st" if all of those files exist, but will yield the form of the
name as stored in the file system if only one case exists? To qualify
as a good answer, it must work on any file system supported by OS X and
ideally not require reading through the entire directory!
I looked at NSFileManager's fileAttributesAtPath:traverseLink: method,
hoping it might include the file name as one of the file's attributes,
but it doesn't. It does include an "NSFileExtensionHidden" key (with a
value of 1 when the extension is hidden). I suppose I could write a
bunch of rather ugly hackish code to use this flag to standardize the
name myself, but it seems that I'm going to an awful lot of work now to
achieve something that ought to be rather simple.
Anyone have a better answer?
Thanks!
Doug