移动和覆盖文件和文件夹

我有一个目录“ Dst Directory”,里面有文件和文件夹,我有“ src Directory”,里面也有文件和文件夹。我要做的是将“ src 目录”的内容移动到“ Dst 目录”,并覆盖任何具有相同名称的文件。因此,例如,‘ Src Directory file.txt’需要移动到‘ Dst Directory’并覆盖现有的 file.txt。同样的道理也适用于某些文件夹,移动一个文件夹并将内容与“ dst 目录”中的同一个文件夹合并

我目前正在使用 shutil.move 将 src 的内容移动到 dst,但是如果文件已经存在并且不合并文件夹,它就不会这样做; 它只是将文件夹放在现有文件夹中。

更新: 为了让事情更清楚一些,我正在做的是将一个归档文件解压缩到 Dst Directory,然后将 Src Directory 的内容移动到那里并重新压缩,从而有效地更新 zip 归档文件中的文件。这将重复添加新文件或新版本的文件等,这就是为什么它需要覆盖和合并

解决: 我使用 distutils.dir _ util 解决了我的问题。Copy _ tree (src,dst) ,这会将文件夹和文件从 src 目录复制到 dst 目录,并在必要时覆盖/合并。希望这能帮到一些人!

希望你能理解, 谢谢!

253473 次浏览

看一下: os.remove删除现有的文件。

改为使用 copy(),它愿意覆盖目标文件。然后,如果您希望第一棵树消失,那么在对它进行迭代之后,只需单独使用 rmtree()就可以了。

Http://docs.python.org/library/shutil.html#shutil.copy

Http://docs.python.org/library/shutil.html#shutil.rmtree

更新:

在源树上执行 os.walk()。对于每个目录,检查它是否存在于目标端,如果缺少,则检查 os.makedirs()。对于每个文件,只需 shutil.copy()和文件将被创建或覆盖,视情况而定。

这将遍历源目录,创建目标目录中不存在的任何目录,并将文件从源目录移动到目标目录:

import os
import shutil


root_src_dir = 'Src Directory\\'
root_dst_dir = 'Dst Directory\\'


for src_dir, dirs, files in os.walk(root_src_dir):
dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1)
if not os.path.exists(dst_dir):
os.makedirs(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
# in case of the src and dst are the same file
if os.path.samefile(src_file, dst_file):
continue
os.remove(dst_file)
shutil.move(src_file, dst_dir)

任何预先存在的文件将首先被删除(通过 os.remove) ,然后被相应的源文件替换。任何已经存在于目标中但不存在于源中的文件或目录将保持不变。

因为上面的方法都不适合我,所以我编写了自己的递归函数。调用 FunctionCopyTree (dir1,dir2)来合并目录。在多平台 Linux 和 Windows 上运行。

def forceMergeFlatDir(srcDir, dstDir):
if not os.path.exists(dstDir):
os.makedirs(dstDir)
for item in os.listdir(srcDir):
srcFile = os.path.join(srcDir, item)
dstFile = os.path.join(dstDir, item)
forceCopyFile(srcFile, dstFile)


def forceCopyFile (sfile, dfile):
if os.path.isfile(sfile):
shutil.copy2(sfile, dfile)


def isAFlatDir(sDir):
for item in os.listdir(sDir):
sItem = os.path.join(sDir, item)
if os.path.isdir(sItem):
return False
return True




def copyTree(src, dst):
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.isfile(s):
if not os.path.exists(dst):
os.makedirs(dst)
forceCopyFile(s,d)
if os.path.isdir(s):
isRecursive = not isAFlatDir(s)
if isRecursive:
copyTree(s, d)
else:
forceMergeFlatDir(s, d)

我也有过类似的问题。我想移动文件和文件夹结构和覆盖现有的文件,但不删除任何在目标文件夹结构。

我用 os.walk()解决了这个问题,递归地调用我的函数,对我想覆盖的文件和不存在的文件夹使用 shutil.move()

它的工作原理类似于 shutil.move(),但其优点是现有文件只被覆盖,而不会被删除。

import os
import shutil


def moverecursively(source_folder, destination_folder):
basename = os.path.basename(source_folder)
dest_dir = os.path.join(destination_folder, basename)
if not os.path.exists(dest_dir):
shutil.move(source_folder, destination_folder)
else:
dst_path = os.path.join(destination_folder, basename)
for root, dirs, files in os.walk(source_folder):
for item in files:
src_path = os.path.join(root, item)
if os.path.exists(dst_file):
os.remove(dst_file)
shutil.move(src_path, dst_path)
for item in dirs:
src_path = os.path.join(root, item)
moverecursively(src_path, dst_path)

如果您还需要用只读标志覆盖文件,请使用:

def copyDirTree(root_src_dir,root_dst_dir):
"""
Copy directory tree. Overwrites also read only files.
:param root_src_dir: source directory
:param root_dst_dir:  destination directory
"""
for src_dir, dirs, files in os.walk(root_src_dir):
dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1)
if not os.path.exists(dst_dir):
os.makedirs(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
try:
os.remove(dst_file)
except PermissionError as exc:
os.chmod(dst_file, stat.S_IWUSR)
os.remove(dst_file)


shutil.copy(src_file, dst_dir)

您可以使用此命令复制覆盖现有文件的目录:

import shutil
shutil.copytree("src", "dst", dirs_exist_ok=True)

dirs_exist_ok参数是在 Python 3.8中添加的。

见文件: https://docs.python.org/3/library/shutil.html#shutil.copytree