I am trying to copy files on Windows with Python 2.7, but sometimes this fails.
shutil.copyfile(copy_file, dest_file)
I get the following I
Maybe do something like this:
path = "some/really/really/long/path/more/than/255/chars.txt"
def copyFile(path, dest, relative=0):
if len(path) > 255:
if not os.sep in path:
raise SomeException()
moveTo, path = path.split(os.sep, 1)
os.chdir(moveTo)
copyFile(path, dest, relative + 1)
else:
path_base = ['..'] * relative
path_rel = path_base + [dest]
shutil.copyfile(path, os.path.join(*path_rel))
This is tested, and does work... however, if the destination is more than 255 chars, you would be back in the same boat. In that case, you may have to move the file several times.
I wasn't sure about the 255 char limit so I stumbled on this post. There I found a working answer: adding \\?\ before the path.
shutil.copyfile("\\\\?\\" + copy_file, dest_file)
edit: I've found that working with long paths causes issues on Windows. Another trick I use is to just shorten the paths:
import win32api
path = win32api.GetShortPathName(path)
Thanks for the answer Gfy. I have a requirement to use relative paths. The \\?\
can't be added successfully to a relative path, so it's necessary to convert to an absolute path first (run from desktop):
import os
def clean_path(path):
path = path.replace('/',os.sep).replace('\\',os.sep)
if os.sep == '\\' and '\\\\?\\' not in path:
# fix for Windows 260 char limit
relative_levels = len([directory for directory in path.split(os.sep) if directory == '..'])
cwd = [directory for directory in os.getcwd().split(os.sep)] if ':' not in path else []
path = '\\\\?\\' + os.sep.join(cwd[:len(cwd)-relative_levels]\
+ [directory for directory in path.split(os.sep) if directory!=''][relative_levels:])
return path
clean_path('samples')
\\?\C:\Users\Username\Desktop\samples
clean_path('\samples')
\\?\C:\Users\Username\Desktop\samples
clean_path('..\samples')
\\?\C:\Users\Username\samples
clean_path('..\..\samples')
\\?\C:\Users\samples
clean_path('C:\Users\Username\Dropbox')
\\?\C:\Users\Username\Dropbox