首页 > 解决方案 > Python -> 复制目录,而另一个进程从中删除/添加文件

问题描述

我使用带有 Python3.6 的 Windows 10。

有两个过程:

我的过程(COPY):复制一个目录X(尽可能多地获取)。(我通过 shutil.copytree 来做)

外部进程 (CREATOR):偶尔删除和重新创建目录 X 中的文件。

问题:当两个进程同时尝试对目录 X 进行操作时,每个进程中的一个偶尔会“崩溃”。我可以处理我的进程中的异常,但不希望外部进程崩溃。

CREATOR:PermissionError:[WinError 32]该进程无法访问该文件,因为它正在被另一个进程使用:文件路径

我只能更改我的流程的代码。有没有办法在不干扰外国进程的情况下复制文件(文件不必完整)?

背景:多个外部进程创建包含许多 html 文件的测试报告。我想在测试执行期间将这些复制到一个位置,并能够从那里查看当前结果。

import shutil, os, stat
import multiprocessing as MP
from time import sleep
import random
from traceback import format_exc

work_dir = r"C:\\tmp\\Report"
dest = r"C:\\tmp\\Report_Copy"

def CREATOR():
    while(True):
        if not(os.path.exists(work_dir)):
            os.mkdir(work_dir)
            print("CREATOR: Created %s" % work_dir)

        for root, dirs, files in os.walk(work_dir, topdown=False):
            # remove current files
            for name in files:
                fullName = os.path.join(root, name)
                os.chmod(fullName, stat.S_IWRITE)
                os.remove(fullName)

        print("CREATOR: Removed %s" % work_dir)

        for i in range(1000):
            tmpPath = os.path.join(work_dir, "result%d" % i)
            with open(tmpPath, "w") as f:
                f.write("voodoo"*50000)
        print("CREATOR: Created 100 files")

        sleep(0)

def COPY():
    while(True):
        try:
            sleep(1)


            # SOLUTION FOR WINDOWS
            #######
            os.system("robocopy %s %s /E >nul 2>&1" %(work_dir, dest))
            #######


            #shutil.copytree(work_dir, dest)
            print("COPY: copied %s to %s" % (work_dir, dest))
            shutil.rmtree(dest)
            print("COPY: removed %s" % dest)
        except:
            print("COPY:\n" + format_exc())
            shutil.rmtree(dest)

if __name__ == "__main__":
    if os.path.exists(work_dir):
        shutil.rmtree(work_dir)

    if os.path.exists(dest):
        shutil.rmtree(dest)

    P1 = MP.Process(target=CREATOR)
    P1.start()

    P2 = MP.Process(target=COPY)
    P2.start()

    P1.join()
    P2.join()

COPY 进程偶尔会失败,但 CREATOR 进程不应该崩溃,因为 COPY 进程正在访问文件。代码只是一个例子。我无法从 CREATOR(外部)进程中更改代码!

标签: pythonconcurrencyshutil

解决方案


我通过在 Windows 下使用特定于操作系统的复制工具解决了这个问题。

我在 COPY Process 中使用了 robocopy 而不是shutil.copytreeshutil虽然在 Linux 下工作)。

os.system("robocopy %s %s /E >nul 2>&1" %(src, dest))

推荐阅读