Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python IOError exception when creating a long file

I get an IOError shown below when trying to open a new file using "open (fname, 'w+')". The complete error message is below.

The file does not exist, but I verified using "os.access(dir_name, os.W_OK)" and "os.path.exists (dir_name)" that the parent directory for the file does exist.

I am wondering if the file name is just too long for Windows, or if I am doing something wrong. Any tips would be appreciated. Thank you very much.

Error message:

IOError: [Errno 2] No such file or directory: 'C:\Documents and Settings\Administrator\op_models\Corp_Network_Nov12\abcde_corporate_nov_12.project\abcde_corporate_nov_12-ctr.rptd.dir\ctr\Non Business Hours for Weeknights\hourly_data_for_2_weeks\1294897740\json.data\Link\0\Link Utilization\analyzer393146160-data0.js'

like image 709
AshD Avatar asked Jan 13 '11 05:01

AshD


3 Answers

Here is some related code which works for me (I have very long file names and paths):

for d in os.walk(os.getcwd()):
    dirname = d[0]
    files = d[2]
    for f in files:
        long_fname = u"\\\\?\\" + os.getcwd() + u"\\" + dirname + u"\\" + f
        if op.isdir(long_fname):
            continue
        fin = open(long_fname, 'rb')
        ...

Note that for me it only worked with a combination of all of the following:

  1. Prepend '\\?\' at the front.

  2. Use full path, not relative path.

  3. Use only backslashes.

  4. In Python, the filename string must be a unicode string, for example u"abc", not "abc".

Also note, for some reason os.walk(..) returned some of the directories as files, so above I check for that.

like image 176
Evgeni Sergeev Avatar answered Oct 05 '22 23:10

Evgeni Sergeev


In the Windows API the maximum path length is limited to 260 characters.

http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx

Update: prepend "\\?\" to the path.

like image 32
cgohlke Avatar answered Oct 05 '22 23:10

cgohlke


You can monkey patch the tarfile module with this:

import tarfile

def monkey_patch_tarfile():
    import os
    import sys
    if sys.platform not in ['cygwin', 'win32']:
        return
    def long_open(name, *args, **kwargs):
    # http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx#maxpath
        if len(name) >= 200:
            if not os.path.isabs(name):
                name = os.path.join(os.getcwd(), name)
            name = "\\\\?\\" + os.path.normpath(name)
        return long_open.bltn_open(name, *args, **kwargs)
    long_open.bltn_open = tarfile.bltn_open
    tarfile.bltn_open = long_open

monkey_patch_tarfile()
like image 34
ticapix Avatar answered Oct 05 '22 23:10

ticapix