簡體   English   中英

Python - 移動和覆蓋文件和文件夾

[英]Python - Move and overwrite files and folders

我有一個目錄“Dst Directory”,里面有文件和文件夾,我有一個“src Directory”,里面也有文件和文件夾。 我想要做的是將 'src Directory' 的內容移動到 'Dst Directory' 並覆蓋任何同名存在的文件。 因此,例如“Src Directory\\file.txt”需要移動到“Dst Directory\\”並覆蓋現有的file.txt。 這同樣適用於某些文件夾,移動文件夾並將內容與“dst 目錄”中的同一文件夾合並

我目前正在使用 shutil.move 將 src 的內容移動到 dst 但如果文件已經存在,它就不會這樣做並且不會合並文件夾; 它只會將文件夾放在現有文件夾中。

更新:為了讓事情更清楚一點,我正在做的是將存檔解壓縮到 Dst 目錄,然后將 Src 目錄的內容移到那里並重新壓縮,有效地更新 zip 存檔中的文件。 這將重復添加新文件或新版本的文件等,這就是為什么它需要覆蓋和合並

已解決:我通過使用 distutils.dir_util.copy_tree(src, dst) 解決了我的問題,這會將文件夾和文件從 src 目錄復制到 dst 目錄,並在需要時覆蓋/合並。 希望能幫助到一些人!

希望有道理,謝謝!

這將遍歷源目錄,創建目標目錄中尚不存在的任何目錄,並將文件從源目錄移動到目標目錄:

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 )。 目標中已存在但源中不存在的任何文件或目錄將保持不變。

改用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() ,文件將被創建或覆蓋,以適當的為准。

由於以上都不適合我,所以我編寫了自己的遞歸函數。 調用函數 copyTree(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)

如果您還需要使用只讀標志覆蓋文件,請使用以下命令:

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)

我有一個類似的問題。 我想移動文件和文件夾結構並覆蓋現有文件,但不刪除目標文件夾結構中的任何內容。

我通過使用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)

您可以使用它來復制目錄覆蓋現有文件:

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

看看: os.remove刪除現有文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM