Способы дублирования файлов с помощью 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
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