dir_util.copy_tree在shutil.rmtree后失败

11 投票
5 回答
5111 浏览
提问于 2025-04-17 12:25

我想在删除一个文件夹后,把它复制到另一个地方:

for i in range(0,3):
   try:
      dir_util.remove_tree("D:/test2")
 #     shutil.rmtree("D:/test2")
      print "removed"
   except: pass

   dir_util.copy_tree("D:/test1", "D:/test2")

   print i

D:/test1 里面有一个空文件,叫做 test_file。使用 dir_util.remove_tree 删除文件夹时一切正常,但用 shutil.rmtree 删除后,只能成功一次,第二次就失败了。输出信息是:

removed
0
removed
Traceback (most recent call last):
  File "test.py", line 53, in <module>
    dir_util.copy_tree("D:/test1", "D:/test2")
  File "C:\Python27\lib\distutils\dir_util.py", line 163, in copy_tree
    dry_run=dry_run)
  File "C:\Python27\lib\distutils\file_util.py", line 148, in copy_file
    _copy_file_contents(src, dst)
  File "C:\Python27\lib\distutils\file_util.py", line 44, in _copy_file_contents
    fdst = open(dst, 'wb')
IOError: [Errno 2] No such file or directory: 'D:/test2\\test_file'

对我来说,使用 shutil.rmtree 更方便,因为它可以处理删除只读文件时的错误。那 dir_util.remove_tree 和 shutil.rmtree 有什么区别呢?为什么在用 rmtree 删除后,第二次用 copy_tree 就不行了?

我在 Windows 7 上运行的是 Python 2.7.2

5 个回答

1

在路径分隔符上似乎有些不一致。
在Windows系统中,你应该使用 "\\"(这个符号需要加上转义符)。而在类Unix系统(比如Linux和Mac)中,则使用 "/"。

你可以使用:
os.path.join("D:\\test2", "test_file") 这样可以让你的代码不依赖于操作系统。
更多信息

4

请查看关于distutil的文档,这个模块是用来“构建和安装Python模块”的(https://docs.python.org/2/library/distutils.html

如果你想把一个文件夹及其内容从一个地方复制到另一个地方,可以看看shutil.copytree(https://docs.python.org/2/library/shutil.html#shutil.copytree

33

看起来这是distutils里的一个bug。如果你复制一个文件夹,然后把它删除,再复制一次就会失败,因为它会缓存所有创建过的目录。为了绕过这个问题,你可以在复制之前清空一下_path_created:

distutils.dir_util._path_created = {}
distutils.dir_util.copy_tree(src, dst)

撰写回答