Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: getting filename case as stored in Windows?

Though Windows is case insensitive, it does preserve case in filenames. In Python, is there any way to get a filename with case as it is stored on the file system?

E.g., in a Python program I have filename = "texas.txt", but want to know that it's actually stored "TEXAS.txt" on the file system, even if this is inconsequential for various file operations.

like image 538
diggums Avatar asked Jan 21 '10 23:01

diggums


5 Answers

Here's the simplest way to do it:

>>> import win32api
>>> win32api.GetLongPathName(win32api.GetShortPathName('texas.txt')))
'TEXAS.txt'
like image 185
Sridhar Ratnakumar Avatar answered Nov 07 '22 17:11

Sridhar Ratnakumar


I had problems with special characters with the win32api solution above. For unicode filenames you need to use:

win32api.GetLongPathNameW(win32api.GetShortPathName(path))
like image 43
CrouZ Avatar answered Nov 07 '22 18:11

CrouZ


This one is standard library only and converts all path parts (except drive letter):

def casedpath(path):
    r = glob.glob(re.sub(r'([^:/\\])(?=[/\\]|$)|\[', r'[\g<0>]', path))
    return r and r[0] or path

And this one handles UNC paths in addition:

def casedpath_unc(path):
    unc, p = os.path.splitunc(path)
    r = glob.glob(unc + re.sub(r'([^:/\\])(?=[/\\]|$)|\[', r'[\g<0>]', p))
    return r and r[0] or path

Note: It is somewhat slower than the file system dependent Win API "GetShortPathName" method, but works platform & file system independent and also when short filename generation is switched off on Windows volumes (fsutil.exe 8dot3name query C:). The latter is recommended at least for performance critical file systems when no 16bit apps rely anymore on that:

fsutil.exe behavior set disable8dot3 1
like image 3
kxr Avatar answered Nov 07 '22 17:11

kxr


>>> import os
>>> os.listdir("./")
['FiLeNaMe.txt']

Does this answer your question?

like image 1
sberry Avatar answered Nov 07 '22 19:11

sberry


and if you want to recurse directories

import os
path=os.path.join("c:\\","path")
for r,d,f in os.walk(path):
    for file in f:
        if file.lower() == "texas.txt":
              print "Found: ",os.path.join( r , file )
like image 1
ghostdog74 Avatar answered Nov 07 '22 17:11

ghostdog74