Python:复制长文件路径Shutil.copyfile

时间:2014-06-04 20:01:31

标签: python-2.7 shutil file-copying

我想使用shutil.copyfile复制太长的python路径。

现在我阅读此Copy a file with a too long path to another directory in Python页面以获得解决方案。我用过:

    shutil.copyfile(r'\\\\?\\' +  ErrFileName,testPath+"\\"+FilenameforCSV+"_lyrErrs"+timestrLyr+".csv")

复制文件,但它给我一个错误:[Errno 2]没有这样的文件或目录:'\\\\?\\ C:\\ ...

任何人都可以让我知道如何使用Shutil.copyfile合并long路径,我上面使用的方法应该允许文件路径中的32k字符,但我甚至不能达到1000并且它给了我这个错误。

1 个答案:

答案 0 :(得分:2)

由于\\?\前缀绕过正常路径处理,路径必须是绝对路径,只能使用反斜杠作为路径分隔符,并且必须是UTF-16字符串。在Python 2中,使用u前缀创建unicode字符串(Windows上为UTF-16)。

shutil.copyfile'rb'模式打开源文件,以'wb'模式打开目标文件,然后以16 KiB块从源复制到目标。给定unicode路径,Python 2通过调用C运行时函数_wfopen打开一个文件,后者又调用Windows宽字符API CreateFileW

shutil.copyfile应该使用长路径,假设它们格式正确。如果它不适合你,我想不出有什么方法可以“强制”它起作用。

这是一个Python 2示例,它创建一个10级目录树,每个目录名为u'a' * 255,并将工作目录中的文件复制到树的叶子中。目标路径大约为2600个字符,具体取决于您的工作目录。

#!python2
import os
import shutil

work = 'longpath_work'
if not os.path.exists(work):
    os.mkdir(work)
os.chdir(work)

# create a text file to copy
if not os.path.exists('spam.txt'):
    with open('spam.txt', 'w') as f:
        f.write('spam spam spam')

# create 10-level tree of directories
name = u'a' * 255
base = u'\\'.join([u'\\\\?', os.getcwd(), name])
if os.path.exists(base):
    shutil.rmtree(base)
rest = u'\\'.join([name] * 9)
path = u'\\'.join([base, rest])
os.makedirs(path)

print 'src directory listing (tree created)'
print os.listdir(u'.')

dest = u'\\'.join([path, u'spam.txt'])
shutil.copyfile(u'spam.txt', dest)
print '\ndest directory listing'
print os.listdir(path)

print '\ncopied file contents'
with open(dest) as f:
    print f.read()

# Remove the tree, and verify that it's removed:
shutil.rmtree(base)
print '\nsrc directory listing (tree removed)'
print os.listdir(u'.')

输出(换行):

src directory listing (tree created)
[u'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
   aaaaa', u'spam.txt']

dest directory listing
[u'spam.txt']

copied file contents
spam spam spam

src directory listing (tree removed)
[u'spam.txt']