Копировать файлы из списка Python

Я делаю небольшую программу на Python для копирования некоторых файлов. Мои имена файлов находятся в списке "selectedList".

Пользователь выбрал исходный каталог "self.DirFilename" и целевой каталог "self.DirDest".

Я использую cp вместо Shutil, потому что я читал, что Shutil работает медленно.

Вот мой код:

for i in selectedList:
    src_dir = self.DirFilename + "/" + str(i) + ".mov"
    dst_dir = self.DirDest
    r = os.system('cp -fr %s %s' % (src_dir, dst_dir))
    if r != 0:
        print 'An error occurred!'**

Я хотел бы, чтобы копия искала исходный каталог для данного имени файла, а затем воссоздавала структуру папок в месте назначения, а также копировала файл.

Любые предложения будут полезны (как и любые очевидные ошибки, которые я делаю) - это моя первая программа на Python, и я почти готов!

Спасибо, Гэвин.


person Gavin Hinfey    schedule 29.04.2013    source источник
comment
Чтобы избежать проблем и проблем безопасности с забавными неэкранированными символами (например, пробелами), сделайте следующее: r = subprocess.call(('cp', '-fr', src_dir, dst_dir + '/'))   -  person pts    schedule 30.04.2013
comment
FYI shutil медленно копирует, потому что размер его буфера составляет всего 16 КБ. Согласно нескольким источникам, больший размер буфера может иметь большое значение (например, blogs.blumetech.com/blumetechs-tech-blog/2011/05/). Для рекурсивных копий изменить размер буфера shutil непросто. См. ссылку выше для альтернативной реализации. Вероятно, огромная разница связана с различными шаблонами поиска на диске.   -  person pts    schedule 30.04.2013
comment
Для меня не очевидно, в чем тут вопрос.   -  person pts    schedule 30.04.2013
comment
Спасибо, я посмотрю на оба.   -  person Gavin Hinfey    schedule 30.04.2013
comment
Я хочу найти каталог для файла, указанного в списке. Найденный файл может находиться на несколько папок вглубь каталога. Как только файл будет найден, я хочу скопировать файл и его структуру папок в каталог назначения. Мой текущий код будет найден только в одном каталоге и скопирован в другой. Имеет ли это смысл?   -  person Gavin Hinfey    schedule 30.04.2013
comment
Вместо print 'An error occurred!' вы можете вызвать исключение и, таким образом, остановить дальнейшую обработку.   -  person pts    schedule 30.04.2013


Ответы (3)


Я думаю, что что-то вроде этого могло бы помочь. Конечно, вы можете захотеть использовать что-то более продвинутое, чем os.system, для вызова cp.

import os

for r, d, f in os.walk(self.DirFilename):
    for file in f:
        f_name, f_ext = os.path.splitext(file)
        if ".mov" == f_ext:
            if f_name in selectedList:
                src_abs_path = os.path.join(r, file)
                src_relative_path = os.path.relpath(src_abs_path, self.DirFilename)
                dst_abs_path = os.path.join(self.DirDest, src_relative_path)
                dst_dir = os.path.dirname(dst_abs_path)
                if not os.path.exists(dst_dir):
                    os.makedirs(dst_dir)
                ret = os.system('cp -fr %s %s' % (src_abs_path, dst_abs_path))
                if ret != 0:
                    print 'An error occurred!'
person Zuljin    schedule 29.04.2013
comment
Спасибо, Zuljin, это сработало, но только для первого элемента в списке. Ваш код немного продвинут для меня, мне потребуется некоторое время, чтобы понять это. Спасибо за вашу помощь. - person Gavin Hinfey; 30.04.2013
comment
Разобравшись с вашим кодом, я обнаружил в нем одну проблему. У меня он отлично работает, но затем зависает после копирования 1 файла. Я получаю эту ошибку: - person Gavin Hinfey; 30.04.2013
comment
Трассировка (последний последний вызов): Файл /Users/gavinhinfey/Desktop/ALEXAFROMEDL.py, строка 119, в DoTheCopy src_abs_path = os.path.join(r, файл) Файл /Library/Frameworks/Python.framework/Versions/2.7 /lib/python2.7/posixpath.py, строка 77, в соединении elif path == '' или path.endswith('/'): AttributeError: объект 'int' не имеет атрибута 'endswith' - person Gavin Hinfey; 30.04.2013
comment
Да, потому что вы перезаписываете переменную r возвращаемым значением os.system. Используйте другое имя переменной там. - person pts; 30.04.2013

См. http://blogs.blumetech.com/blumetechs-tech-blog/2011/05/faster-python-file-copy.html для реализации рекурсивной копии на чистом Python.

Вы можете использовать os.walk, чтобы найти нужный файл:

def find_files(...):
    for ... in os.walk(...):
        if ...:
            yield filename

for name in find_files(...):
   copy(name, ...)
person pts    schedule 29.04.2013

person    schedule
comment
found = [(p, os.path.join(self.DirDest, os.path.relpath(p, self.DirFilename))) для p в найдено] ^ SyntaxError: недопустимый синтаксис - person Gavin Hinfey; 30.04.2013
comment
@GavinHinfey странно, я не получаю синтаксическую ошибку. На какую часть жалуется? - person cmd; 30.04.2013
comment
конец переменной, найденной в строке, которую я процитировал. - person Gavin Hinfey; 30.04.2013
comment
@GavinHinfey А, нашел, раньше в строке отсутствовала скобка, исправлено - person cmd; 30.04.2013