Sophy
Sophy

Reputation: 411

Python long filename support broken in Windows

I write Python script to copy files; unfortunately it keeps failing because filename is too long(>256). Is there anyway to deal with that problem?

I'm using Python 2.5.4 and Windows XP.

Cheers,

Upvotes: 13

Views: 10578

Answers (5)

Amos Egel
Amos Egel

Reputation: 1196

Another thing that works for me is to change directory into the place to which I want to copy:

import os
import shutil

def copyfile_long_path(src, dst):
    
    src_abs = os.path.abspath(src)
    dst_abs = os.path.abspath(dst)
    
    cwd = os.getcwd()
    os.chdir(os.path.dirname(dst))
    shutil.copyfile(src_abs, os.path.filename(dst))
    os.chdir(cwd)
    
    if not os.path.isfile(dst_abs):    
        raise Exception("copying file failed")

Upvotes: 0

Amos Egel
Amos Egel

Reputation: 1196

This answer by uDev suggests to add

# Fix long path access:
import ntpath
ntpath.realpath = ntpath.abspath

It seems to work for me.

Upvotes: 0

Helga
Helga

Reputation: 51

For anyone else looking for solution here:

  1. You need to add prefix \\?\ as already stated, and make sure string is unicode;
  2. If you are using shutil, especially something like shutil.rmtree with onerror method, you'll need to modify it too to add prefix as it gets stripped somewhere on the way.

You'll have to write something like:

def remove_dir(directory):
    long_directory = '\\\\?\\' + directory
    shutil.rmtree(long_directory, onerror=remove_readonly)

def remove_readonly(func, path, excinfo):
    long_path = path
    if os.sep == '\\' and '\\\\?\\' not in long_path:
        long_path = '\\\\?\\' + long_path
    os.chmod(long_path, stat.S_IWRITE)
    func(long_path)

This is an example for Python 3.x so all strings are unicode.

Upvotes: 5

Martin v. Löwis
Martin v. Löwis

Reputation: 127447

In order to use the \\?\ prefix (as already proposed), you also need to make sure you use Unicode strings as filenames, not regular (byte) strings.

Upvotes: 9

bcat
bcat

Reputation: 8941

Use paths beginning with the string \\?\.

Upvotes: 13

Related Questions