Is it possible Python can distinguish capital letter and small letter in the path of Windows?

eryk sun eryksun at gmail.com
Tue Oct 11 08:48:08 EDT 2016


On Tue, Oct 11, 2016 at 10:34 AM,  <jfong at ms4.hinet.net> wrote:
> I have two files in the Q:\lib directory:
>
> Q:\lib>dir
> 2007/03/11 AM 08:02        5,260  lib_MARK.so
> 2007/03/11 AM 08:02        4,584  lib_mark.so
>
> Under Python 3.4.4 I got:
>
>>>> f = open('lib_MARK.so', 'br')
>>>> data = f.read()
>>>> f.close()
>>>> len(data)
> 4584
>
> I know Windows won't, but can Python make it true?

Windows can do case-sensitive file operations, but it's not easy in
Python. You have to use the Windows API directly via _winapi, ctypes,
or PyWin32, depending on your needs.

First, disable the registry setting that forces the kernel's object
manager to be case insensitive for operations on its own object types
(i.e. object directories and symlinks) and I/O object types (e.g.
devices, files). Here's a .reg file to do this:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel]
"obcaseinsensitive"=dword:00000000

You have to reboot after making this change.

This alone doesn't make the Windows API case sensitive, but it does
enable individual CreateFile calls to be case sensitive, via the POSIX
semantics flag. Once you have a handle for the target file or
directory, you can accomplish most file operations via
GetFileInformationByHandleEx [1] and SetFileInformationByHandle [2].

[1]: https://msdn.microsoft.com/en-us/library/aa364953
[2]: https://msdn.microsoft.com/en-us/library/aa365539

Here's a basic example, based on your example with "lib_mark.so" and
"lib_MARK.so":

    import os
    import _winapi

    GENERIC_READ = 0x80000000
    GENERIC_WRITE = 0x40000000
    OPEN_EXISTING = 3
    FILE_SHARE_READ = 1
    FILE_SHARE_WRITE = 2
    FILE_SHARE_DELETE = 4
    FILE_FLAG_POSIX_SEMANTICS = 0x001000000

    def create_file(path,
                    access=GENERIC_READ | GENERIC_WRITE,
                    sharing=FILE_SHARE_READ | FILE_SHARE_WRITE,
                    disposition=OPEN_EXISTING,
                    flags=0):
        sharing |= FILE_SHARE_DELETE
        flags |= FILE_FLAG_POSIX_SEMANTICS
        return _winapi.CreateFile(path, access, sharing, 0,
                                  disposition, flags, 0)

    >>> os.listdir('.')
    ['lib_MARK.so', 'lib_mark.so']

    >>> h1 = create_file('lib_MARK.so')
    >>> len(_winapi.ReadFile(h1, 10000)[0])
    5260

    >>> h2 = create_file('lib_mark.so')
    >>> len(_winapi.ReadFile(h2, 10000)[0])
    4584



More information about the Python-list mailing list