将路径过长的文件复制到Python中的另一个目录

将路径过长的文件复制到Python中的另一个目录,python,copy,Python,Copy,我试图用Python2.7在Windows上复制文件,但有时会失败 shutil.copyfile(copy_file, dest_file) 我得到以下错误: [Errno 2] No such file or directory 但是文件确实存在!问题是文件的路径太长。(>255个字符) 如何复制这些文件?在其他应用程序中打开它们不是问题 若要创建路径过长的文件,请使用尽可能长的文件名创建一个文件,并将包含该文件的文件夹向下移动到树结构的较深位置 我一直在尝试这些方法,但都没有成功: 也

我试图用Python2.7在Windows上复制文件,但有时会失败

shutil.copyfile(copy_file, dest_file)
我得到以下错误:

[Errno 2] No such file or directory
但是文件确实存在!问题是文件的路径太长。(>255个字符)

如何复制这些文件?在其他应用程序中打开它们不是问题

若要创建路径过长的文件,请使用尽可能长的文件名创建一个文件,并将包含该文件的文件夹向下移动到树结构的较深位置

我一直在尝试这些方法,但都没有成功:

也许可以这样做:

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

这是经过测试的,确实有效。。。但是,如果目的地超过255个字符,您将回到同一条船上。在这种情况下,您可能需要多次移动文件。

我不确定255个字符的限制,所以我偶然发现了。在那里,我找到了一个有效的答案:在路径之前添加\\?\

shutil.copyfile("\\\\?\\" + copy_file, dest_file)
编辑: 我发现使用长路径会导致Windows出现问题。我使用的另一个技巧是缩短路径:

import win32api
path = win32api.GetShortPathName(path)
谢谢你的回答。我需要使用相对路径。无法将
\\?\
成功添加到相对路径,因此必须先转换为绝对路径(从桌面运行):


尝试将您的工作目录更改为包含该文件的目录(如有必要,一次将一个目录移深),然后在
shutil.copyfile
中使用相对路径,而不是完整路径。我收到以下错误:WindowsError:[错误2]系统无法找到opgegeven BEST和niet vinden:“复制”(系统无法找到文件)“复制”是我路径中的一个文件夹。我一直在尝试相对路径,但我无法让它工作。更改工作目录并对长文件名尝试os.path.exists(),结果为False。我的目标目录接近255,但仍然低于255。win32api对我来说仍然失败,但第一个解决方案非常有效
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