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.
Here's the simplest way to do it:
>>> import win32api
>>> win32api.GetLongPathName(win32api.GetShortPathName('texas.txt')))
'TEXAS.txt'
I had problems with special characters with the win32api solution above. For unicode filenames you need to use:
win32api.GetLongPathNameW(win32api.GetShortPathName(path))
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
>>> import os
>>> os.listdir("./")
['FiLeNaMe.txt']
Does this answer your question?
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 )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With