Уведомления

Группа в Telegram: @pythonsu

#1 Март 6, 2015 19:53:15

Guljaca
От:
Зарегистрирован: 2011-07-11
Сообщения: 93
Репутация: +  0  -
Профиль   Отправить e-mail  

Копирование каталога с перезаписью

Суть, программа должна копировать указанную директорию вместе с содержимым по указанному пути.
Проблема 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)



Офлайн

#2 Март 6, 2015 21:40:36

Guljaca
От:
Зарегистрирован: 2011-07-11
Сообщения: 93
Репутация: +  0  -
Профиль   Отправить e-mail  

Копирование каталога с перезаписью

В общем, если кому пригодится

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)



Офлайн

#3 Март 7, 2015 17:22:56

Kasta_neda
Зарегистрирован: 2014-06-08
Сообщения: 210
Репутация: +  6  -
Профиль   Отправить e-mail  

Копирование каталога с перезаписью

Можно и хеш проверить что бы не перезаписывать если файл не изменился

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)

Офлайн

#4 Март 10, 2015 13:39:57

Xyanide
Зарегистрирован: 2014-02-11
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

Копирование каталога с перезаписью

Kasta_neda
Можно и хеш проверить что бы не перезаписывать если файл не изменился
Для проверки измененных и новых файлов, я бы рекомендовал использовать filecmp. Намного быстрее и проще. У меня есть по логике почти аналогичный кусок кода: проверить, какие файлы изменились и какие появились новые. Так вот объем контента с помощью filecmp в 1.5 Гб проверяется за пару секунд. В вашем случае это будет утомительно долго.



Это просто какой-то Python!

Отредактировано Xyanide (Март 10, 2015 13:44:59)

Офлайн

#5 Март 10, 2015 14:09:12

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Копирование каталога с перезаписью

На днях упёрся в такую же проблему. В моём случае в качестве решения сошло и

def do_copy(src, dst):
    subprocess.check_call(['cp', '-r', '-f', src, dst])

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version