Copie un archivo con una ruta demasiado larga a otro directorio en Python

Estoy intentando copiar archivos en Windows con Python 2.7, pero a veces esto falla.

shutil.copyfile(copy_file, dest_file) 

Me sale el siguiente IOError:

 [Errno 2] No such file or directory 

Pero el archivo existe! El problema es que la ruta del archivo es demasiado larga. (> 255 caracteres)

¿Cómo copio estos archivos? No es un problema abrirlos en otras aplicaciones.

Para crear un archivo con una ruta demasiado larga, cree un archivo con un nombre de archivo tan largo como sea posible y mueva la carpeta que contiene más profundamente hacia abajo en una estructura de árbol.

He estado probando algunos de estos métodos sin éxito: http://timgolden.me.uk/python/win32_how_do_i/copy-a-file.html

No estaba seguro del límite de 255 caracteres, así que me topé con esta publicación . Allí encontré una respuesta de trabajo: agregar \\? \ Antes de la ruta.

 shutil.copyfile("\\\\?\\" + copy_file, dest_file) 

edición: he encontrado que trabajar con rutas largas causa problemas en Windows. Otro truco que utilizo es acortar los caminos:

 import win32api path = win32api.GetShortPathName(path) 

Gracias por la respuesta Gfy . Tengo el requisito de utilizar rutas relativas. \\?\ No se puede agregar con éxito a una ruta relativa, por lo que es necesario convertir primero a una ruta absoluta (ejecutarse desde el escritorio):

 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 

Tal vez hacer algo como esto:

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

Esto se prueba y funciona … sin embargo, si el destino tiene más de 255 caracteres, estaría de vuelta en el mismo barco. En ese caso, es posible que deba mover el archivo varias veces.