【问题标题】:Python: copy long file path Shutil.copyfilePython:复制长文件路径Shutil.copyfile
【发布时间】:2014-07-25 15:20:04
【问题描述】:

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

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

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

复制文件但它给了我一个错误:[Errno 2] No such file or directory: '\\\\?\\C:\\...

谁能告诉我如何将长路径与 Shutil.copyfile 合并,我上面使用的方法应该允许文件路径中包含 32k 个字符,但我什至无法达到 1000 个并且它给了我这个错误。

【问题讨论】:

  • 它是'\\\\?\\'。您不能在单个反斜杠上结束原始字符串,因此您不能为此使用原始字符串。这也是不能替换正斜杠的情况,即'//?/'
  • 嗨 eryksun 当我使用 '\\\\?\\' [Errno 22] invalid mode ('rb') or filename: 运行它时,它给了我这个错误,现在我确定文件名称是正确的,我已经关闭了文件,我不明白为什么会出现这种情况
  • 还有其他处理长路径的方法吗?我有很大的路径,路径字符串可能长达 1000 或 1500 个字符
  • 嗨 eryksun 这仍然给我同样的错误,[Errno 2] 没有这样的文件或目录,我们可以使用 python shell 脚本强制复制长路径吗?
  • 我的基本路径是一个绝对路径("C:\\test1234\\test4567\\...) 并且使用 \\.join 将剩余路径添加到基本路径的循环中,并且它仍然给我同样的错误,文件系统是 NTFS。你认为 python shell 脚本可以在长路径上强制复制吗?有没有办法做到这一点?

标签: python-2.7 shutil file-copying


【解决方案1】:

由于\\?\前缀绕过了正常的路径处理,路径需要是绝对的,只能使用反斜杠作为路径分隔符,并且必须是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']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-15
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多