Способы дублирования файлов с помощью Python

Раздел: Python -> Файловый ввод-вывод

Копирование файлов в Python: основные подходы

Для копирования файлов в Python чаще всего применяется модуль shutil, содержащий высокоуровневые функции. Самый простой способ - функция shutil.copy(). Она переносит содержимое файла и его права доступа, но не сохраняет метаданные (время создания, изменения).

import shutil
shutil.copy('source.txt', 'dest.txt')

ввод программ на python (ввод данных в программе python)

В примере файл source.txt копируется в dest.txt. Если целевой файл уже существует, он перезаписывается. Путь назначения может быть именем файла или каталогом. В случае указания каталога файл копируется в него с исходным именем.

Возможные проблемы:

  • Отсутствие source.txt - возникает FileNotFoundError. Решение: проверка существования через os.path.exists().
  • Недостаток прав на чтение или запись - PermissionError. Решение: запуск с соответствующими правами или обработка исключения.
  • Целевая папка не существует - FileNotFoundError. Решение: создание папки с помощью os.makedirs().

Метод подходит для быстрого копирования, когда метаданные не требуются.

Как скопировать файл с сохранением метаданных (shutil.copy2)?

Функция shutil.copy2() ведёт себя как shutil.copy(), но дополнительно копирует метаданные (время модификации, доступа). Используется, когда необходимо сохранить временные характеристики файла.

import shutil
shutil.copy2('source.txt', 'dest_copy2.txt')

Python file io (ввод-вывод файлов в python)

Особенность: на некоторых платформах (например, Windows) метаданные могут копироваться не полностью. Следует тестировать на целевой системе.

Как скопировать только данные без атрибутов (shutil.copyfile)?

shutil.copyfile() копирует только содержимое файла, не затрагивая права доступа и метаданные. Подходит для случаев, когда важен лишь контент.

import shutil
shutil.copyfile('source.txt', 'dest_content.txt')

Python temp files (временные файлы в python)

Важно: целевой файл не должен быть открыт в другой программе на запись. Иначе возникает PermissionError.

Как эффективно копировать большие файлы с буферизацией (shutil.copyfileobj)?

shutil.copyfileobj() копирует данные между файловыми объектами с заданным размером буфера. Это позволяет контролировать объём памяти при работе с крупными файлами.

import shutil
with open('source_large.dat', 'rb') as src:
    with open('dest_large.dat', 'wb') as dst:
        shutil.copyfileobj(src, dst, length=65536)

Python index files (индексация файлов в python)

Параметр length задаёт размер буфера в байтах (по умолчанию 16 КБ). Увеличение значения ускоряет копирование, но потребляет больше памяти.

Проблема: при открытии текстовых файлов в режиме 'r' копия может исказить символы из-за кодировки. Использовать двоичный режим 'rb'/'wb'.

Как использовать системную команду cp (os.system)?

os.system('cp source dest') вызывает команду cp операционной системы. Работает только в Unix-подобных средах. Полезно для интеграции с уже существующими скриптами.

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

File python class (класс для работы с файлами в python)

Ограничение: нет обработки ошибок в Python, все сообщения уходят в stdout/stderr. Не рекомендуется для кроссплатформенного кода.

Как скопировать небольшой файл с помощью pathlib?

Path.read_bytes() и Path.write_bytes() позволяют скопировать файл целиком в память и записать. Подходит для файлов размером до нескольких мегабайт.

from pathlib import Path
data = Path('source_small.txt').read_bytes()
Path('dest_small.txt').write_bytes(data)

Python file utf 8 (кодировка utf-8 для файлов в python)

Недостаток: для больших файлов может занять много оперативной памяти. Лучше использовать shutil.

Как реализовать копирование с собственным буфером?

Низкоуровневое копирование вручную даёт полный контроль над процессом. Например, для прогресс-бара или обработки ошибок.

BUFFER_SIZE = 4096
with open('source.txt', 'rb') as src:
    with open('dest_manual.txt', 'wb') as dst:
        while chunk := src.read(BUFFER_SIZE):
            dst.write(chunk)

Цикл читает блоки по 4 КБ и записывает их. Размер буфера можно менять.

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

- Python log file (логирование в файл в python)
- Python file methods (методы работы с файлами в python)
- File models in python (модели файлов в python)

Расширенные примеры копирования файлов в Python

1. Копирование с проверкой существования и созданием директорий

Пример объединяет проверку источника, создание целевой папки и копирование с обработкой ошибок.

Пример
import shutil
import os
from pathlib import Path

def safe_copy(source, destination):
    if not os.path.exists(source):
        raise FileNotFoundError(f"Исходный файл {source} не найден")
    dest_path = Path(destination)
    dest_path.parent.mkdir(parents=True, exist_ok=True)
    try:
        shutil.copy2(source, destination)
        print(f"Файл скопирован в {destination}")
    except PermissionError:
        print(f"Нет прав на запись в {destination}")
        raise

safe_copy('data/data.txt', 'backup/2025/03/data.txt')
Файл скопирован в backup/2025/03/data.txt

Возможная ошибка: если dest_path.parent существует, mkdir с exist_ok=True не выдаст ошибки. Иначе потребуется создавать вложенные папки вручную.

2. Копирование с логированием и повторными попытками

При сетевых сбоях бывает полезно повторить копирование несколько раз.

Пример
import shutil
import time
import logging

logging.basicConfig(level=logging.INFO)

def copy_with_retry(src, dst, retries=3, delay=1):
    for attempt in range(retries):
        try:
            shutil.copy(src, dst)
            logging.info(f"Копирование успешно: {src} -> {dst}")
            return
        except Exception as e:
            logging.warning(f"Попытка {attempt+1} не удалась: {e}")
            if attempt < retries - 1:
                time.sleep(delay)
    raise RuntimeError(f"Не удалось скопировать {src} после {retries} попыток")

copy_with_retry('/mnt/remote/data.txt', './local_data.txt')
WARNING:root:Попытка 1 не удалась: [Errno 2] No such file or directory
WARNING:root:Попытка 2 не удалась: [Errno 2] No such file or directory
...

3. Копирование всех файлов из каталога с фильтрацией по расширению

Скопировать только файлы .txt из source_dir в dest_dir.

Пример
import shutil
import os
from pathlib import Path

def copy_by_extension(source_dir, dest_dir, extension='.txt'):
    src_path = Path(source_dir)
    dest_path = Path(dest_dir)
    dest_path.mkdir(parents=True, exist_ok=True)
    for file in src_path.glob(f'*{extension}'):
        if file.is_file():
            shutil.copy(file, dest_path / file.name)

copy_by_extension('./docs', './archive', '.txt')
(ничего не выводит, файлы скопированы в ./archive)

4. Копирование с индикатором прогресса (tqdm)

Для крупных файлов полезно отображать прогресс.

Пример
import shutil
from tqdm import tqdm
import os

def copy_with_progress(src, dst):
    size = os.path.getsize(src)
    with open(src, 'rb') as fsrc:
        with open(dst, 'wb') as fdst:
            with tqdm(total=size, unit='B', unit_scale=True, desc=src) as pbar:
                while chunk := fsrc.read(8192):
                    fdst.write(chunk)
                    pbar.update(len(chunk))

copy_with_progress('bigfile.iso', 'bigfile_copy.iso')
bigfile.iso: 100%|██████████| 1.00G/1.00G [00:10<00:00, 97.2MB/s]

5. Параллельное копирование нескольких файлов с помощью threading

Ускоряет копирование множества мелких файлов.

Пример
import shutil
import threading
import os
from pathlib import Path

def copy_file(src, dst):
    try:
        shutil.copy2(src, dst)
        print(f"OK: {src}")
    except Exception as e:
        print(f"FAIL: {src} -> {e}")

def parallel_copy(file_list, dest_dir, max_threads=4):
    Path(dest_dir).mkdir(parents=True, exist_ok=True)
    threads = []
    for src in file_list:
        name = os.path.basename(src)
        dst = os.path.join(dest_dir, name)
        t = threading.Thread(target=copy_file, args=(src, dst))
        threads.append(t)
        t.start()
    for t in threads:
        t.join()

files = ['a.txt', 'b.txt', 'c.txt']
parallel_copy(files, 'backup')
OK: a.txt
OK: b.txt
OK: c.txt

Копирование файла в Python - comments

En
Python copy file (python)