Note that there are some explanatory texts on larger screens.

plurals
  1. POIn python on OSX with HFS+ how can I get the correct case of an existing filename?
    primarykey
    data
    text
    <p>I am storing data about files that exist on a OSX HFS+ filesystem. I later want to iterate over the stored data and figure out if each file still exists. For my purposes, I care about filename case sensitivity, so if the case of a filename has changed I would consider the file to no longer exist.</p> <p>I started out by trying</p> <pre><code>os.path.isfile(filename) </code></pre> <p>but on a normal install of OSX on HFS+, this returns True even if the filename case does not match. I am looking for a way to write a isfile() function that cares about case even when the filesystem does not.</p> <p>os.path.normcase() and os.path.realpath() both return the filename in whatever case I pass into them.</p> <p>Edit:</p> <p>I now have two functions that seem to work on filenames limited to ASCII. I don't know how unicode or other characters might affect this.</p> <p>The first is based off answers given here by omz and Alex L.</p> <pre><code>def does_file_exist_case_sensitive1a(fname): if not os.path.isfile(fname): return False path, filename = os.path.split(fname) search_path = '.' if path == '' else path for name in os.listdir(search_path): if name == filename : return True return False </code></pre> <p>The second is probably even less efficient.</p> <pre><code>def does_file_exist_case_sensitive2(fname): if not os.path.isfile(fname): return False m = re.search('[a-zA-Z][^a-zA-Z]*\Z', fname) if m: test = string.replace(fname, fname[m.start()], '?', 1) print test actual = glob.glob(test) return len(actual) == 1 and actual[0] == fname else: return True # no letters in file, case sensitivity doesn't matter </code></pre> <p>Here is a third based off DSM's answer.</p> <pre><code>def does_file_exist_case_sensitive3(fname): if not os.path.isfile(fname): return False path, filename = os.path.split(fname) search_path = '.' if path == '' else path inodes = {os.stat(x).st_ino: x for x in os.listdir(search_path)} return inodes[os.stat(fname).st_ino] == filename </code></pre> <p>I don't expect that these will perform well if I have thousands of files in a single directory. I'm still hoping for something that feels more efficient.</p> <p>Another shortcoming I noticed while testing these is that they only check the filename for a case match. If I pass them a path that includes directory names none of these functions so far check the case of the directory names.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload