Problem with case insensitive volumes

D

dmoore

Does anyone know of a way to get the unique pathname for files stored
on FAT32 or other case insensitive drives?

For example:

os.path.samefile('/media/usbkey/file1.jpg','/media/usbkey/FILE1.jpg')

returns True

but, is there a simple way to determine whether '/media/usbkey/
file1.jpg' or '/media/usbkey/FILE1.jpg' is the actual representation
on the device.

it matters because operations like this have meaning:

os.rename('/media/usbkey/file1.jpg','/media/usbkey/tmp')
os.rename('/media/usbkey/tmp','/media/usbkey/FILE1.jpg')

If I have a program that scans a directory for files and compares
against a stored list of pathnames, I want to be able to determine not
only that the file still exists but whether or not it has changed case
(i.e. '/media/usbkey/file1.jpg' has become '/media/usbkey/FILE1.jpg').

Any takers?
 
D

Dave Angel

dmoore said:
Does anyone know of a way to get the unique pathname for files stored
on FAT32 or other case insensitive drives?

For example:

os.path.samefile('/media/usbkey/file1.jpg','/media/usbkey/FILE1.jpg')

returns True

but, is there a simple way to determine whether '/media/usbkey/
file1.jpg' or '/media/usbkey/FILE1.jpg' is the actual representation
on the device.

it matters because operations like this have meaning:

os.rename('/media/usbkey/file1.jpg','/media/usbkey/tmp')
os.rename('/media/usbkey/tmp','/media/usbkey/FILE1.jpg')

If I have a program that scans a directory for files and compares
against a stored list of pathnames, I want to be able to determine not
only that the file still exists but whether or not it has changed case
(i.e. '/media/usbkey/file1.jpg' has become '/media/usbkey/FILE1.jpg').

Any takers?
os;walk will tell you the correct case for each node. So if it gives
you a different case than the stored form, you have your answer.
 
S

spillz

os;walk will tell you the correct case for each node.   So if it gives
you a different case than the stored form, you have your answer.

Thanks, although I was hoping that wouldn't be the answer (I have to
compare a LOT of files).
 
S

spillz

What is so tough about something like:

base, dirs, files = next(os.walk(dirn))  # older: os.walk(dirn).next()
current = dict((name.upper() for name in dirs + files)
...
changed = some_name == current[some_name.upper()]
...

not so fast. :) Consider:

/my/path/to/usbkey/and/file

everything up to "/my/path/to/usbkey" is case sensitive. only the "and/
file" is case insensitive. but my list of stored paths might include
all images under "/my". thus

/my/path/to/usbkey/and/file1==/my/path/to/usbkey/and/FILE1
/my/path/to/usbkey/and/file1==/my/path/to/usbkey/AND/FILE1
but
/my/path/to/usbkey/and/file1!=/my/path/TO/usbkey/AND/FILE1

so to do this right I'd need to establish which parts of the path are
case insensitive. being able to retrieve the actual path from an
equivalent representation would be so much simpler.
 
G

Gabriel Genellina

/my/path/to/usbkey/and/file

everything up to "/my/path/to/usbkey" is case sensitive. only the "and/
file" is case insensitive. but my list of stored paths might include
all images under "/my". thus

/my/path/to/usbkey/and/file1==/my/path/to/usbkey/and/FILE1
/my/path/to/usbkey/and/file1==/my/path/to/usbkey/AND/FILE1
but
/my/path/to/usbkey/and/file1!=/my/path/TO/usbkey/AND/FILE1

so to do this right I'd need to establish which parts of the path are
case insensitive. being able to retrieve the actual path from an
equivalent representation would be so much simpler.

I use this function on Windows to obtain the true case name of a file:

<code>
from win32api import FindFiles
from win32file import FILE_ATTRIBUTE_DIRECTORY
from os.path import normpath, split, join

def truecase(fullpath, _cache={}):
"""
Normalize fullpath, returning names using the
same case as actually used in the filesystem.
"""
fullpath = normpath(fullpath)
dirname, filename = split(fullpath)
dirname = dirname.lower()
if not filename:
# drive letter
result = _cache[dirname] = dirname.upper()
return result
if dirname in _cache: dirname = _cache[dirname]
elif dirname: dirname = truecase(dirname)
finddata = FindFiles(fullpath)
if not finddata:
import errno, os
raise IOError(errno.ENOENT, os.strerror(errno.ENOENT), fullpath)
if len(finddata)!=1:
raise ValueError("Too many results for %r" % fullpath)
attr = finddata[0][0]
filename = finddata[0][8]
result = join(dirname, filename)
if attr & FILE_ATTRIBUTE_DIRECTORY:
_cache[result.lower()] = result
return result
</code>

truecase("c:")=="C:"
truecase("C:\\")=="C:\\"
truecase("c:\\")=="C:\\"
truecase("C:\\TeMp")=="C:\\TEMP"
truecase("C:\\TeMp\\")=="C:\\TEMP\\"
truecase(r"C:\Documents and Settings\gabriel")==r"C:\Documents and
Settings\gabriel"
truecase(r"c:\dOcUmEnTs aNd SeTtInGs\GaBrIeL\mIS DOCUMENTOS\105_3 - nist -
sPECIFICATIONS vOLUMETRIC fIELD sTANDARD.PDF")==r"C:\Documents and
Settings\gabriel\Mis documentos\105_3 - NIST - Specifications Volumetric
Field Standard.pdf"
truecase(r"E:\prog\test\compface\Debug\No existe.txt")
 
S

spillz

I use this function on Windows to obtain the true case name of a file:

very nice. I think the python bindings to the gnome GIO library
*might* provide what I need on the linux side.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top