Копирование файлов в python
Если вам нужно скопировать файл с помощью Python, но вы не знаете, как это сделать, вы попали по адресу.
Когда вы хотите скопировать файл, у вас может быть несколько сценариев: копирование только содержимого, использование конечного каталога в качестве параметра, копирование метаданных и так далее. Именно поэтому Python предлагает различные альтернативы при копировании файла. Здесь мы рассмотрим наиболее распространенные из них, использующие модуль shutil.
Копирование файла в Python с помощью функции copy
Я уже говорил, он определяется внутри модуля shutil.
Главная особенность этой функции заключается в том, что она копирует содержимое файла и его разрешения, но не копирует другие метаданные, такие как оригинальные даты создания и модификации.
Как именно это работает?
Данная функция позволяет задать следующие параметры:
- src: Полный путь или имя исходного файла. Это может быть строка или объект PathLike.
- dst: Путь к файлу назначения. Если путь является каталогом, исходный файл будет скопирован в каталог, принимая в качестве имени имя исходного файла.
- follow_symlinks (по умолчанию, True): Если follow_symlinks равно false и src является символической ссылкой, dst будет создан как символическая ссылка. Если параметр follow_symlinks равен true и src является символической ссылкой, dst будет копией файла, на который ссылается src.
Давайте рассмотрим некоторые примеры использования:
Копирование метаданных с помощью copy2
Если вам дополнительно нужно скопировать метаданные файла, вы можете использовать функцию copy2. Эта функция ведет себя точно так же, как функция копирования в предыдущем разделе, за исключением того, что она также сохраняет метаданные из исходного файла в целевом файле.
Копировать только содержимое файла
Если вам нужно скопировать только содержимое файла, вы можете использовать функцию copyfile(src, dst, follow_symlinks=True). Эта функция создает копию исходного файла src в целевой файл dst.
Еще одна вещь, которую следует помнить об этой функции, заключается в том, что у вас должна быть возможность записи в место назначения, иначе будет выброшено исключение OSError.
Копирование содержимого файла с помощью объектов файла
Сохраните статью в социальных сетях, чтобы не потерять.Похожие записи
Иногда нам нужно преобразовать Excel или CSV в другой формат, в этот раз мне нужно…
Недавно я показал вам, как форматировать даты в JavaScript, но мы делали это вручную, извлекая…
Python становится все популярнее благодаря относительной простоте изучения, универсальности и другим преимуществам. Правда, у начинающих разработчиков нередко возникают проблемы при работе с файлами и файловой системой. Просто потому, что они знают не все команды, которые нужно знать.
Эта статья предназначена как раз для начинающих разработчиков. В ней описаны 8 крайне важных команд для работы с файлами, папками и файловой системой в целом. Все примеры из этой статьи размещены в Google Colab Notebook (ссылка на ресурс — в конце статьи).
Показать текущий каталог
Самая простая и вместе с тем одна из самых важных команд для Python-разработчика. Она нужна потому, что чаще всего разработчики имеют дело с относительными путями. Но в некоторых случаях важно знать, где мы находимся.
Относительный путь хорош тем, что работает для всех пользователей, с любыми системами, количеством дисков и так далее.
Так вот, для того чтобы показать текущий каталог, нужна встроенная в Python OS-библиотека:
Ее легко запомнить, так что лучше выучить один раз, чем постоянно гуглить. Это здорово экономит время.
Имейте в виду, что я использую Google Colab, так что путь /content является абсолютным.
Проверяем, существует файл или каталог
Прежде чем задействовать команду по созданию файла или каталога, стоит убедиться, что аналогичных элементов нет. Это поможет избежать ряда ошибок при работе приложения, включая перезапись существующих элементов с данными.
Функция os.path.exists () принимает аргумент строкового типа, который может быть либо именем каталога, либо файлом.
В случае с Google Colab при каждом запуске создается папка sample_data. Давайте проверим, существует ли такой каталог. Для этого подойдет следующий код:
Эта же команда подходит и для работы с файлами:
Если папки или файла нет, команда возвращает false.
Объединение компонентов пути
В предыдущем примере я намеренно использовал слеш "/" для разделителя компонентов пути. В принципе это нормально, но не рекомендуется. Если вы хотите, чтобы ваше приложение было кроссплатформенным, такой вариант не подходит. Так, некоторые старые версии ОС Windows распознают только слеш "\" в качестве разделителя.
Но не переживайте, Python прекрасно решает эту проблему благодаря функции os.path.join (). Давайте перепишем вариант из примера в предыдущем пункте, используя эту функцию:
Создание директории
Ну а теперь самое время создать директорию с именем test_dir внутри рабочей директории. Для этого можно использовать функцию
os.mkdir():
Давайте посмотрим, как это работает на практике.
Если же мы попытаемся создать каталог, который уже существует, то получим исключение.
Именно поэтому рекомендуется всегда проверять наличие каталога с определенным названием перед созданием нового:
Еще один совет по созданию каталогов. Иногда нам нужно создать подкаталоги с уровнем вложенности 2 или более. Если мы все еще используем os.mkdir (), нам нужно будет сделать это несколько раз. В этом случае мы можем использовать os.makedirs (). Эта функция создаст все промежуточные каталоги так же, как флаг mkdir -p в системе Linux:
Вот что получается в результате.
Показываем содержимое директории
Еще одна полезная команда — os.listdir(). Она показывает все содержимое каталога.
Команда отличается от os.walk (), где последний рекурсивно показывает все, что находится «под» каталогом. os.listdir () намного проще в использовании, потому что просто возвращает список содержимого:
В некоторых случаях нужно что-то более продвинутое — например, поиск всех CSV-файлов в каталоге «sample_data». В этом случае самый простой способ — использовать встроенную библиотеку glob:
Перемещение файлов
Самое время попробовать переместить файлы из одной папки в другую. Рекомендованный способ — еще одна встроенная библиотека shutil.
Сейчас попробуем переместить все CSV-файлы из директории «sample_data» в директорию «test_dir». Ниже — пример кода для выполнения этой операции:
Кстати, есть два способа выполнить задуманное. Например, мы можем использовать библиотеку OS, если не хочется импортировать дополнительные библиотеки. Как os.rename, так и os.replace подходят для решения задачи.
Но обе они недостаточно «умные», чтобы позволить перемесить файлы в каталог.
Чтобы все это работало, нужно явно указать имя файла в месте назначения. Ниже — код, который это позволяет сделать:
Здесь функция os.path.basename () предназначена для извлечения имени файла из пути с любым количеством компонентов.
Другая функция, os.replace (), делает то же самое. Но разница в том, что os.replace () не зависит от платформы, тогда как os.rename () будет работать только в системе Unix / Linux.
Еще один минус — в том, что обе функции не поддерживают перемещение файлов из разных файловых систем, в отличие от shutil.
Поэтому я рекомендую использовать shutil.move () для перемещения файлов.
Копирование файлов
Аналогичным образом shutil подходит и для копирования файлов по уже упомянутым причинам.
Если нужно скопировать файл README.md из папки «sample_data» в папку «test_dir», поможет функция shutil.copy():
Удаление файлов и папок
Теперь пришел черед разобраться с процедурой удаления файлов и папок. Нам здесь снова поможет библиотека OS.
Когда нужно удалить файл, нужно воспользоваться командой os.remove():
Если требуется удалить каталог, на помощь приходит os.rmdir():
Однако он может удалить только пустой каталог. На приведенном выше скриншоте видим, что удалить можно лишь каталог level_3. Что если мы хотим рекурсивно удалить каталог level_1? В этом случае зовем на помощь shutil.
Функция shutil.rmtree() сделает все, что нужно:
Пользоваться ею нужно с осторожностью, поскольку она безвозвратно удаляет все содержимое каталога.
Собственно, на этом все. 8 важных операций по работе с файлами и каталогами в среде Python мы знаем. Что касается ссылки, о которой говорилось в анонсе, то вот она — это Google Colab Network с содержимым, готовым к запуску.
Когда дело доходит до использования Python для копирования файлов, есть два основных способа: использовать модуль shutil или модуль os. Все методы ОС, которые мы здесь показываем, являются методами, которые позволяют нам выполнять команды из нашего кода, который мы будем использовать для выполнения команды копирования (Windows) или команды cp (Unix).
Вы заметите, что многие из этих методов, как в модуле shutil, так и в модуле os, имеют очень похожую функциональность (что не должно вызывать удивления), но каждый из них очень немного отличается по функциональности.
С помощью модуля shutil
Модуль shutil предлагает несколько высокоуровневых методов копирования файлов. Вот основные из них:
copyfile
Этот метод копирует содержимое одного файла в другой. Предоставленное ему место назначения должно быть файлом с возможностью записи и иметь другое имя, чем исходный файл. Если имена совпадают, это вызовет ошибку. Если целевой файл уже существует, он будет заменен вновь скопированным файлом.
Синтаксис этого метода:
Например, следующий код скопирует файл с именем file1.txt в файл с именем file2.txt:
Одна интересная и потенциально полезная функция shutil.copyfile – логический аргумент follow_symlinks. Если установлено значение False и исходный файл является символической ссылкой, то вместо копирования файла будет создана новая символическая ссылка.
Этот метод очень похож на copyfile, с основным отличием в том, что он не только копирует содержимое исходного файла, но и делает еще один шаг вперед, а также копирует разрешения файловой системы. Копирование прав доступа к файлам – нетривиальная задача для большинства языков программирования, так что это хорошая возможность.
Каждый из этих параметров такой же, как и в методе copyfile. Например, следующий код скопирует «file1.txt» в «file3.txt».
copy2
Как и предыдущие методы, метод copy2 идентичен методу копирования, но помимо копирования содержимого файла он также пытается сохранить все метаданные исходного файла. Если платформа не позволяет полностью сохранять метаданные, то copy2 не возвращает ошибку, а просто сохраняет любые метаданные, которые могут.
Опять же, эти параметры такие же, как и в предыдущих командах, которые мы уже упоминали.
Например, следующий код скопирует «file1.txt» в «file4.txt», а также сохранит метаданные исходного файла «file1.txt».
Как видно из выполнения нашего кода выше, «file1.txt» был скопирован в «file4.txt». Однако вы могли заметить, что дата создания была сохранена в новом файле, в отличие от shutil.copy, который копирует «file1.txt» в «file3.txt» и дает ему новую дату создания.
copyfileobj
Этот метод копирует содержимое исходного файла в целевой файл из текущей позиции исходного файла. Это означает, что если вы читаете данные из объекта исходного файла, то позиция, в которой вы прекращаете чтение, – это позиция, с которой copyfileobj начинает копирование.
Значения параметров исходного и целевого файлов аналогичны предыдущим командам, но теперь они относятся к объектам. Параметр длины является необязательным и представляет размер буфера, который представляет собой количество битов, хранящихся в памяти во время процесса копирования. Эта опция может быть полезна при копировании очень больших файлов, поскольку она может ускорить процесс копирования и избежать неконтролируемого использования памяти.
Как мы видим, чтобы использовать copyfileobj, нам нужно открыть файлы в двоичном режиме (который является частью «b» от «rb» и «wb»). Кроме того, исходный файл должен быть открыт, как доступный для чтения, а целевой файл должен быть открыт, как доступный для записи (части «r» и «w» соответственно).
С помощью модуля os
Модуль os предоставляет возможность использовать функциональные возможности операционной системы для копирования ваших файлов. Мы приведем примеры, которые работают как для Windows, так и для Unix. Они различаются из-за используемых команд оболочки, поэтому не забудьте обратить внимание на то, как каждый вызов функции помечен в комментариях Python.
popen
Этот метод открывает канал к вашей команде. Однако обратите внимание, что этот метод устарел в Python 2.6, поэтому мы не рекомендуем его использовать, если в этом нет необходимости. В качестве альтернативы документация Python советует нам использовать вместо этого методы из модуля подпроцесса.
Здесь возвращаемое значение представляет собой файловый объект, подключенный к каналу. Этот объект может быть прочитан или записан в зависимости от режима. По умолчанию установлен режим «r», который позволяет читать содержимое файла.
В приведенном ниже примере файл file1.txt будет скопирован в file6.txt:
Выполнение команды таким образом точно такое же, как если бы вы запускали ее непосредственно из командной строки вашего терминала.
system
Этот метод выполняет указанную команду в подоболочке. Он доступен как для Unix, так и для Windows. Синтаксис следующий:
Здесь команда – это строка, содержащая команду оболочки DOS или Unix. В нашем случае сюда мы поместим команду copy или cp.
Например, следующий код скопирует file1.txt в file7.txt.
Это выглядит идентично предыдущей команде os.popen, которую мы только что использовали, но команда выполняется в подоболочке, что означает, что она выполняется в отдельном потоке параллельно с вашим исполняемым кодом. Чтобы дождаться его завершения, вам нужно вызвать .wait() для объекта, возвращаемого os.system.
С помощью модуля subprocess
Модуль subprocess предназначен для замены некоторых методов в модуле os (в частности, методов os.system и os.spawn *), и он представляет два основных метода доступа к командам операционной системы. Это методы call и check_output. Еще раз, для систем Unix команду «copy file1.txt file2.txt» следует заменить на «cp file1.txt file2.txt».
call Method
Документация Python рекомендует нам использовать метод call для запуска команды из операционной системы.
Параметр args будет включать нашу команду оболочки. Однако небольшое предостережение, поскольку документация Python предупреждает нас, что использование shell = True может быть угрозой безопасности.
Используя этот вызов функции, мы можем запустить нашу команду копирования следующим образом:
Как показывает пример выше, нам просто нужно передать строку с помощью команды оболочки, как и раньше.
Как и ожидалось, операционная система скопирует file1.txt в файл с именем file8.txt.
Метод check_output
Здесь параметр args включает команду оболочки, которую мы хотим использовать. Еще раз, документация Python предупреждает нас об использовании shell = True, поэтому используйте этот метод с осторожностью.
В следующем коде мы скопируем «file1.txt» в «file9.txt» с помощью команды check_output:
И, как и все команды, которые мы показали в этой статье, это скопирует файл «file1.txt» в указанное нами место назначения.
Заключение
Python предлагает нам множество различных способов копирования файлов, некоторые из которых являются частью набора методов. Другие используют некоторые мощные методы для выполнения команд в оболочке, которые используют команды copy или cp.
В наших предыдущих руководствах мы изучили некоторые операции с файлами Python, такие как чтение, запись и удаление.
Мы можем скопировать файл в Python, используя различные методы в нижеперечисленных модулях,
- модуль shutil
- модуль os
- модуль subprocess
В этом руководстве мы научимся использовать различные методы, предоставляемые вышеуказанными модулями, для копирования файла в Python.
1 shutil модуль
Модуль shutil предоставляет несколько простых в использовании методов, с помощью которых мы можем удалить или скопировать файл. Давайте посмотрим на различные методы, определенные в этом модуле, специально используемые для копирования.
1 copyfileobj()
Метод copyfileobj() копирует содержимое исходного файла в целевой файл, используя соответствующие файловые объекты. Давайте посмотрим на код ниже,
Примечание: объекты файлов должны указывать на позиции 0 (начальную позицию) для соответствующих исходных и целевых файлов, чтобы скопировать все содержимое.
2 copyfile()
Метод copyfile() копирует содержимое из исходного файла в целевой файл, используя пути к файлам. Он возвращает путь к целевому файлу. Путь к целевому файлу должен быть доступен для записи, иначе возникнет исключение OSerror.
Следует иметь в виду, что метод позволяет использовать только пути к файлам, а не каталоги.
3 copy()
Этот метод копирует исходный файл в целевой файл или целевой каталог. В отличие от copyfile() , метод copy() позволяет использовать целевой каталог в качестве аргумента, а также копирует права доступа к файлу. copy() возвращает путь к целевому файлу после копирования содержимого.
В целевом месте назначения создается файл с именем file.txt со всем содержимым и разрешениями, скопированными из /Users/test/file.txt.
4 copy2()
Метод copy2() используется точно так же, как метод copy() . Они также работают аналогичным образом, за исключением того факта, что copy2() также копирует метаданные из исходного файла.
2 Модуль os
1 popen()
Метод popen() создает канал к команде cmd. Метод возвращает файловый объект, подключенный к каналу cmd. Взгляните на код ниже,
С помощью этого метода мы можем выполнять другие обычные команды.
2 system()
Метод system() напрямую вызывает и выполняет аргумент команды в подоболочке. Его возвращаемое значение зависит от ОС, в которой запущена программа. Для Linux это статус выхода, тогда как для Windows это значение, возвращаемое системной оболочкой.
Читайте также: