Copier un fichier avec un chemin trop long vers un autre répertoire en Python
j'essaie de copier des fichiers sur Windows avec Python 2.7, mais parfois cela échoue.
shutil.copyfile(copy_file, dest_file)
j'ai le IOError:
[Errno 2] No such file or directory
mais le fichier existe! Le problème est que le chemin du fichier est trop long. (> 255 caractères)
comment copier ces fichiers? Il n'est pas un problème pour les ouvrir dans d'autres applications.
pour créer un fichier avec un chemin trop long, créez un fichier avec un nom de fichier aussi long que possible et déplacez le contenant un dossier plus profond dans une structure d'arbre.
j'ai essayé certaines de ces méthodes sans succès: http://timgolden.me.uk/python/win32_how_do_i/copy-a-file.html
3 réponses
Je n'étais pas sûr de la limite de 255 char alors je suis tombé sur ce post. Là, j'ai trouvé une réponse de travail: Ajouter \\?\ avant le chemin d'accès.
shutil.copyfile("\\?\" + copy_file, dest_file)
modifier: J'ai découvert que travailler avec long paths provoque des problèmes sur Windows. Un autre truc que j'utilise est de raccourcir les chemins:
import win32api
path = win32api.GetShortPathName(path)
Merci pour la réponse Gfy. J'ai l'obligation d'utiliser des chemins relatifs. \?\
ne peut pas être ajouté avec succès à un chemin relatif, il est donc nécessaire de passer à un chemin absolu en premier (exécuter depuis le bureau):
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
Peut-être faire quelque chose comme ceci:
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))
C'est testé et fonctionne... toutefois, si la destination est plus de 255 caractères, vous seriez de retour dans le même bateau. Dans ce cas, vous pourriez avoir à déplacer le fichier plusieurs fois.