Гид по технологиям

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

5 min read Python Обновлено 31 Dec 2025
Как копировать файлы в Python быстро
Как копировать файлы в Python быстро

Иллюстрация копирования файлов с помощью Python

Зачем учиться копировать файлы в Python

Копирование файлов — простая и полезная операция, которая часто встречается в автоматизации задач: резервное копирование, подготовка тестовых данных, миграция логов и т. п. Освоив базовые методы, вы сможете создавать надёжные скрипты и избегать распространённых ошибок (повторная запись, потеря метаданных, проблемы с правами доступа).

Краткое определение: “метаданные” — это атрибуты файла (время модификации, права доступа и т. п.).

Требования для копирования файлов в Python

  • Самый простой и надёжный путь — встроенная библиотека shutil (не требует установки сторонних пакетов).
  • Для системных вызовов пригодятся os и subprocess.
  • Для чтения/записи “вручную” достаточно стандартной функции open().
  • Права доступа: убедитесь, что ваш процесс имеет чтение исходного файла и запись в папку назначения.
  • На разных ОС команды и поведение могут отличаться (Windows: copy, xcopy; Linux/macOS: cp).

Совет: используйте абсолютные пути или проверяйте текущую рабочую директорию перед операцией (os.getcwd()).

Копирование файлов с помощью shutil (рекомендуемый способ)

Модуль shutil — встроенный, простой и функциональный. Он предоставляет несколько функций для разных потребностей:

  • shutil.copy(src, dst) — копирует содержимое файла; метаданные не сохраняются.
  • shutil.copy2(src, dst) — копирует содержимое и метаданные (атрибуты файла).
  • shutil.copyfile(src, dst) — как copy, но требует, чтобы dst был путём к файлу (не папке).
  • shutil.copyfileobj(fsrc, fdst) — копирует между файловыми объектами (позволяет контролировать буфер).

Пример использования shutil.copy:

import shutil
sourceFile = "C:/Users/some_directories/my_folder/copy.txt"
destinationFile = "C:/Users/some_directories/destination/newFile.txt"

shutil.copy(sourceFile, destinationFile, follow_symlinks=True)

Если нужно также сохранить метаданные (время создания/модификации, права), используйте copy2:

import shutil
shutil.copy2(sourceFile, destinationFile, follow_symlinks=True)

Когда использовать copyfileobj — пример поблочного копирования (полезно при больших файлах):

import shutil

with open("C:/Users/some_directories/my_folder/copy.txt", "rb") as src, \
     open("C:/Users/some_directories/destination/newFile.txt", "wb") as dst:
    shutil.copyfileobj(src, dst)

Примечание: follow_symlinks=True указывает следовать символическим ссылкам. Если вы работаете в одной рабочей директории и не используете ссылки, аргумент можно опустить.

Копирование с помощью модуля os

Модуль os позволяет запускать команды оболочки через os.system() или os.popen(). Это простой, но менее переносимый метод — команды зависят от ОС.

Пример для Windows (copy):

import os
os.system('copy source.txt destination.txt')

Пример для Linux/macOS (cp):

import os
os.system('cp source.txt destination.txt')

os.popen похож на os.system, но возвращает файловый объект с выводом команды:

import os
stream = os.popen('cp source.txt destination.txt')
print(stream.read())

Ограничения:

  • Команды выполняются в оболочке, поэтому возможны риски инъекций, если вы подставляете переменные без экранирования.
  • Поведение зависит от текущей рабочей директории.

Копирование с помощью subprocess

subprocess даёт более явный контроль над выполнением внешних команд и над ошибками.

Пример для Windows:

import subprocess as sp
sp.call("copy sourceFile destinationFile", shell=True)

Пример для Linux/macOS:

import subprocess as sp
sp.call("cp sourceFile destinationFile", shell=True)

Более современный и безопасный вариант — использовать list-формат и отключать shell=True (если возможно):

import subprocess as sp
sp.run(["cp", "sourceFile", "destinationFile"], check=True)

Преимущества subprocess:

  • Контроль возвратных кодов, ошибок и вывода.
  • Меньше риск инъекций при использовании списка аргументов.

Копирование без библиотек (чистая реализация через open)

Иногда полезно понимать, как работает копирование “вручную” — это даёт контроль над буфером, прогрессом и обработкой ошибок.

Пример простого копирования:

sourcePath = "C:/Users/source_directories/my_folder/copy.txt"
destinationPath = "C:/Users/some_directories/destination_directories/newFile.txt"

with open(sourcePath, "rb") as read:
    with open(destinationPath, "wb") as myfile:
        myfile.write(read.read())

Реализация с буфером для больших файлов:

def copy_file_buffered(src, dst, buf_size=16*1024):
    with open(src, 'rb') as fsrc:
        with open(dst, 'wb') as fdst:
            while True:
                buf = fsrc.read(buf_size)
                if not buf:
                    break
                fdst.write(buf)

Функция-обёртка с базовой валидацией:

def copyFile(source=None, destination=None):
    if not (source and destination):
        print("Пожалуйста, укажите пути source и destination")
        return
    try:
        with open(source, "rb") as read:
            with open(destination, "wb") as myfile:
                myfile.write(read.read())
    except Exception as e:
        print("Ошибка при копировании:", e)

# Пример вызова
# copyFile(sourcePath, destinationPath)

Безопасность и права доступа

  • Всегда проверяйте права на чтение исходного файла и запись в папку назначения.
  • Не выполняйте shell-команды с неподготовленными строками, полученными от пользователя — возможна команда-инъекция.
  • Для временных файлов используйте модуль tempfile и безопасные функции создания временных имён.
  • При копировании конфиденциальных данных убедитесь, что файлы временно не остаются с глобальными правами (chmod).

Когда методы не подходят (ограничения и контрпримеры)

  • Если нужно копировать между удалёнными машинами, shutil и open подходят только при доступе к смонтированной файловой системе. Для SFTP/FTP/HTTP используйте paramiko, ftplib или requests.
  • Для атомарной замены файла применяйте временный файл + os.replace(), чтобы избежать состояния гонки.
  • При копировании больших объёмов данных лучше использовать потоковую передачу с контролем скорости и проверкой контрольной суммы (hashlib).

Пример атомарной записи:

import os
import tempfile

def atomic_copy(src, dst):
    dstdir = os.path.dirname(dst)
    with tempfile.NamedTemporaryFile(dir=dstdir, delete=False) as tmp:
        with open(src, 'rb') as fsrc:
            tmp.write(fsrc.read())
    os.replace(tmp.name, dst)

Альтернативные подходы

  • Для сетевого копирования: rsync (внешняя утилита), paramiko (SFTP), smbprotocol (SMB/CIFS).
  • Для бинарной сериализации больших структур — использовать базы данных или object storage (S3) вместо файловой системы.
  • Для асинхронных операций в приложениях с высокой нагрузкой — asyncio + aiofiles (библиотека).

Ментальные модели и эвристики

  • “Принцип единой ответственности”: функция должна делать одну вещь — копировать, логировать или проверять права, но не всё одновременно.
  • “Сначала проверь, потом действуй”: проверяйте доступ и свободное место перед большим копированием.
  • “Не доверяй данным извне”: экранируйте имена файлов и пути, особенно если они приходят из сети.

Роли и чек-листы (что проверить перед применением скрипта)

Для разработчика:

  • Проверить пути (абсолютные/относительные).
  • Добавить обработку исключений и логирование.
  • Написать unit-тесты на мелкие сценарии.

Для администратора:

  • Убедиться в правах пользователя на чтение/запись.
  • При необходимости настроить резервирование и мониторинг.

Для тестировщика:

  • Проверить поведение при отсутствующем исходном файле.
  • Проверить поведение при отсутствии места на диске.
  • Проверить атомарность (замена файла во время чтения).

Сниппеты и шпаргалка (быстрый доступ)

Копирование и сохранение метаданных:

import shutil
shutil.copy2('src.txt', 'dst.txt')

Копирование с проверкой ошибок:

import shutil
import os

try:
    shutil.copy('src.txt', 'dst.txt')
except IOError as e:
    print('I/O error:', e)
except Exception as e:
    print('Ошибка:', e)

Проверка свободного места (пример для POSIX):

import shutil
total, used, free = shutil.disk_usage("/")
print("Свободно:", free)

Критерии приёмки

  • Файл успешно копируется в целевую папку при корректных путях и правах.
  • Метаданные сохраняются при использовании copy2.
  • В случае ошибки — функция возвращает информативное сообщение и не оставляет частично записанных файлов (при необходимости используется атомарная замена).
  • Для большого файла используется буфер, и операция не потребляет всю память.

Краткая справка (глоссарий)

  • shutil — модуль для операций высокого уровня с файлами и директориями.
  • os — модуль для взаимодействия с операционной системой.
  • subprocess — модуль для запуска внешних процессов.
  • метаданные — атрибуты файла (время, права и т. п.).

Итог и рекомендации

  • Если копируете файлы локально — используйте shutil (copy или copy2 в зависимости от потребности в метаданных).
  • Для вызова системных команд предпочитайте subprocess с явным списком аргументов.
  • Для сетевых копий и специальных протоколов применяйте соответствующие библиотеки (paramiko, boto3 для S3 и т. п.).
  • Всегда учитывайте безопасность: права доступа, проверку входных данных и атомарность операций.

Важно: практикуйтесь на тестовых данных и добавляйте логирование — это упростит диагностику проблем в проде.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как попросить рекомендацию при поиске работы
Карьера

Как попросить рекомендацию при поиске работы

Как быстро и эффективно писать деловые письма
Письма

Как быстро и эффективно писать деловые письма

Покупательская персона: руководство и шаблон
Маркетинг

Покупательская персона: руководство и шаблон

Как создать инфографику в Adobe Illustrator
Графический Дизайн

Как создать инфографику в Adobe Illustrator

Как построить профессиональную сеть в Facebook
Профессиональный нетворкинг

Как построить профессиональную сеть в Facebook

Блок‑схема в Pages на Mac
Руководство

Блок‑схема в Pages на Mac