Найти - Пользователи
Полная версия: Копирование каталога с перезаписью
Начало » Python для новичков » Копирование каталога с перезаписью
1
Guljaca
Суть, программа должна копировать указанную директорию вместе с содержимым по указанному пути.
Проблема 1: shutil.copytree не поддерживает перезапись. Пробовал решить удалением всех папок перед копированием, но:
Проблема 2: При удалении, shutil.rmtree сама создает пустые папки, сама не может их удалить, в результате чего делает сиппуко.

import os
import shutil
def my_copytree(src, dst, symlinks=False, ignore=None):
    if os.path.isdir(dst):
            shutil.rmtree
    if not os.path.exists(dst):
        os.makedirs(dst)
    for item in os.listdir(src):
        print (item)
        if not ".tmp" in item:
            s = os.path.join(src, item)
            d = os.path.join(dst, item)
            if os.path.isdir(s):
                shutil.copytree(s, d, symlinks, ignore)
            else:
                shutil.copy2(s, d)
if __name__ == "__main__":
    src = "D:/_Library from SSD_/My Documents/__My_Documents__/__Record__/"
    dst_sav = "c:/__My_Documents_Copy__/"
    my_copytree(src, dst_sav)
Guljaca
В общем, если кому пригодится
import os
import shutil
def my_copytree(src, dst, symlinks=False, ignore=None):
    print ("Запуск процедуры копирования")
    #print ("Составление списка файлов исходного каталога")
    # Root - полный путь к каталогу
    # Files - список файлов в каталоге по указанному пути
    # dirs - список папок в каталоге по указанному пути
    for root, dirs, files in os.walk(src):
        for name in files:
            #print ("Получение полного пути к файлам")
            src_file = os.path.join(root, name)
            #print ("Состаление списка путей для копий")
            # Замена начала адресса, указанного как источник, конечным
            dst_file = src_file.replace(src,os.path.join(dst,os.path.split(src)[-1]))
            #print ("Проверка существования каталогов")
            #print ("Создание отсутствующих каталогов")
            if not os.path.exists(dst_file):
                # На этом этапе, в dst_file записаны адресса всех файлов
                # Исправление ошибок в симвалах пути
                path = os.path.realpath(dst_file)
                # Получение пути к каталогу, в котором находится файл
                dir = os.path.split(path)[0]
                # Проверка наличия папок на диске
                if not os.path.exists(dir):
                    # Создание папок
                    os.makedirs(dir)
            # Открытие файлов для чтения и записи
            f1 = open(src_file,'rb')
            f2 = open(dst_file,'wb')
            dump = f1.read()
            f2.write(dump)
if __name__ == "__main__":
    src = "D:/_Library from SSD_/My Documents/__My_Documents__/__Record__/"
    dst_sav = "c:/__My_Documents_Copy__/"
    my_copytree(src, dst_sav)
Kasta_neda
Можно и хеш проверить что бы не перезаписывать если файл не изменился
import os
import hashlib
import shutil
import time
def md5hash(filePath):# проверка хеша файла
    file = open(filePath, 'rb')
    m = hashlib.md5()
    while True:
        data = file.read(8000)
        if not data:
            break
        m.update(data)
    return m.hexdigest()
def my_copytree(src, dst, symlinks=False, ignore=None):
    print ("Запуск процедуры копирования")
    tit1 = time.time()
    #print ("Составление списка файлов исходного каталога")
    # Root - полный путь к каталогу
    # Files - список файлов в каталоге по указанному пути
    # dirs - список папок в каталоге по указанному пути
    for root, dirs, files in os.walk(src):
        for name in files:
            
            #print ("Получение полного пути к файлам")
            src_file = os.path.join(root, name)
            #print ("Состаление списка путей для копий")
            # Замена начала адресса, указанного как источник, конечным
            dst_file = src_file.replace(src,os.path.join(dst,os.path.split(src)[-1]))
            s = md5hash(src_file)
            d = ''
            try:
                d = md5hash(dst_file)
            except: pass
            
            if s == d:
                #print dst_file
                pass
            #print ("Проверка существования каталогов")
            #print ("Создание отсутствующих каталогов")
            if not os.path.exists(dst_file):
                # На этом этапе, в dst_file записаны адресса всех файлов
                # Исправление ошибок в симвалах пути
                path = os.path.realpath(dst_file)
                # Получение пути к каталогу, в котором находится файл
                dir = os.path.split(path)[0]
                # Проверка наличия папок на диске
                if not os.path.exists(dir):
                    # Создание папок
                    os.makedirs(dir)
            # Открытие файлов для чтения и записи
            f1 = open(src_file,'rb')
            f2 = open(dst_file,'wb')
            dump = f1.read()
            f2.write(dump)
    tit2 = time.time()
    print 'скорость обработки: %.2f' % (tit2-tit1)
if __name__ == "__main__":
    src = raw_input('src: ')
    dst_sav = raw_input('sav: ')
    #проверка если файл а не каталог
    if os.path.isfile(src):  #является ли объект файлом      
        shutil.copyfile(src, dst_sav)
    elif os.path.isdir(src): #является ли каталогом  
        my_copytree(src, dst_sav)
Xyanide
Kasta_neda
Можно и хеш проверить что бы не перезаписывать если файл не изменился
Для проверки измененных и новых файлов, я бы рекомендовал использовать filecmp. Намного быстрее и проще. У меня есть по логике почти аналогичный кусок кода: проверить, какие файлы изменились и какие появились новые. Так вот объем контента с помощью filecmp в 1.5 Гб проверяется за пару секунд. В вашем случае это будет утомительно долго.
Shaman
На днях упёрся в такую же проблему. В моём случае в качестве решения сошло и
def do_copy(src, dst):
    subprocess.check_call(['cp', '-r', '-f', src, dst])
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB