Python -> Копировать каталог, в то время как другой процесс удаляет / добавляет файлы из / в него - PullRequest
0 голосов
/ 11 января 2019

Я работаю с Windows 10 с Python3.6.

Есть два процесса:

Мой процесс (КОПИЯ): Скопируйте каталог X (получите как можно больше). (я делаю это через shutil.copytree)

Зарубежный процесс (СОЗДАТЕЛЬ): Время от времени удаляет и воссоздает файлы в каталоге X.

Проблема: Один из каждого процесса иногда «падает», когда оба процесса пытаются одновременно работать с каталогом X. Я могу обрабатывать исключения в моем процессе, но не хочу, чтобы происходил сбой внешнего процесса.

CREATOR: PermissionError: [WinError 32] Процесс не может получить доступ к файлу, поскольку он используется другим процессом: Filepath

Я могу изменить только код своего процесса. Есть ли способ скопировать файлы (файлы не обязательно должны быть полными) без нарушения внешнего процесса?

Справочная информация: Множество сторонних процессов создают отчеты о тестировании, содержащие множество 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 (иностранного) процесса!

1 Ответ

0 голосов
/ 11 января 2019

Это было решено мной с помощью специального инструмента копирования ОС под Windows.

Я использовал robocopy в COPY Process вместо shutil.copytree (хотя shutil работал под Linux).

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