Python IOError exception when creating a long file

ぐ巨炮叔叔 提交于 2019-12-10 03:01:12

问题


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'


回答1:


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.




回答2:


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()



回答3:


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.




回答4:


If it's not the length of the filename, it's the contents of the filename...

Python is treating '\12' as a control sequence.

>>> fn='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'
>>> print fn
C:\Documents and Settings\Administrator\op_models\Corp_Network_Nov12bcde_corporate_nov_12.projectbcde_corporate_nov_12-ctr.rptd.dir\ctr\Non Business Hours for Weeknights\hourly_data_for_2_weeks
94897740\json.data\Link\Link Utilizationnalyzer393146160-data0.js

Using raw strings for Windows filenames will help:

>>> fn=r'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'
>>> print fn
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

Update

Alternatively, use forward slashes '/' instead of backslashes '\', since these will work on all operating systems and will save you hassles with backslashes right at the end of a pathname as in your comments.

See also os.path.join() .

Update 2

Simplified demonstration of problem:

>>> open('.\12\n\r\file.txt')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: '.\n\n\r\x0cile.txt'
>>> open('./12/n/r/file.txt')
<open file './12/n/r/file.txt', mode 'r' at 0x7ff83f98>

C:\Users\johnysweb>copy .\12\n\r\file.txt con
Blah
        1 file(s) copied.



回答5:


Check the length of the entire path and then append the necessary Windows long path format. It should be noted that this doesn't work for accessing data from remote directories i.e. paths that begin with '\\some_remote_location\..' so you will need to map that directory locally in order to get "long path" to work.

if len(path_and_file) > 250: #I think the max is 260 but I left a buffer :)
    path_and_file = '\\\\?\\'+path_and_file


来源:https://stackoverflow.com/questions/4677234/python-ioerror-exception-when-creating-a-long-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!