Python文件/文件夹复制功能

一、基础工具库介绍

Python标准库中的shutil模块是主要工具:

python 复制代码
import shutil
import os

二、文件复制基础

1. 复制单个文件

python 复制代码
# 保留元数据(修改时间等)
shutil.copy2('source.txt', 'destination.txt')

# 仅复制内容
shutil.copy('source.txt', 'backup/')  # 自动保留文件名

# 文件流方式(适合大文件)
with open('source.txt', 'rb') as src, open('dest.txt', 'wb') as dst:
    shutil.copyfileobj(src, dst, length=16*1024)  # 16KB缓冲区

三、目录复制进阶

1. 简单目录复制

python 复制代码
# 复制整个目录(目标目录必须不存在)
shutil.copytree('src_dir', 'dst_dir')

# 允许覆盖已存在目录(Python 3.8+)
shutil.copytree('src', 'existing_dir', dirs_exist_ok=True)

2. 自定义复制过程

python 复制代码
def ignore_patterns(*patterns):
    def _ignore(path, names):
        ignored = []
        for pattern in patterns:
            ignored.extend(fnmatch.filter(names, pattern))
        return set(ignored)
    return _ignore

# 排除.pyc文件和临时文件
shutil.copytree('src', 'dst', ignore=ignore_patterns('*.pyc', '*.tmp'))

# 带进度回调的复制
def copy_progress(src, dst, *, follow_symlinks=True):
    print(f"Copying {src} => {dst}")

shutil.copytree('src', 'dst', copy_function=copy_progress)

四、高级自定义实现

当需要完全控制复制流程时,可以手动实现:

python 复制代码
def deep_copy(src, dst, symlinks=False):
    if not os.path.exists(dst):
        os.makedirs(dst)
        shutil.copystat(src, dst)
    
    for item in os.listdir(src):
        src_path = os.path.join(src, item)
        dst_path = os.path.join(dst, item)
        
        if os.path.isdir(src_path):
            deep_copy(src_path, dst_path, symlinks)
        else:
            if os.path.exists(dst_path):
                if os.path.samefile(src_path, dst_path):
                    continue
                os.remove(dst_path)
            if symlinks and os.path.islink(src_path):
                linkto = os.readlink(src_path)
                os.symlink(linkto, dst_path)
            else:
                shutil.copy2(src_path, dst_path)

五、异常处理要点

python 复制代码
try:
    shutil.copytree('src', 'dst')
except shutil.Error as e:
    print(f'Directory not copied. Error: {e}')
except OSError as e:
    print(f'OSError: {e.strerror}')

六、性能优化建议

  1. 批量小文件:使用shutil.copytree的默认实现
  2. 超大文件:使用copyfileobj分块复制
  3. 网络存储:增加缓冲区大小(例如16*1024*1024即16MB)
  4. 并行处理:对独立子目录使用多线程/多进程

七、完整示例代码

python 复制代码
import shutil
import os
from pathlib import Path

def smart_copy(src, dst, overwrite=False, ignore=None):
    """智能复制器"""
    src = Path(src)
    dst = Path(dst)

    if src.is_file():
        if dst.is_dir():
            dst = dst / src.name
        if dst.exists():
            if overwrite:
                dst.unlink()
            else:
                raise FileExistsError(f"{dst} already exists")
        shutil.copy2(str(src), str(dst))
        return

    if not src.is_dir():
        raise ValueError("Source path invalid")

    if dst.exists():
        if overwrite:
            if dst.is_dir():
                shutil.rmtree(dst)
            else:
                dst.unlink()
        else:
            raise FileExistsError(f"{dst} already exists")

    shutil.copytree(
        str(src),
        str(dst),
        symlinks=True,
        ignore=ignore,
        copy_function=shutil.copy2,
        dirs_exist_ok=overwrite
    )

# 使用示例
smart_copy(
    '/data/project',
    '/backup/project_2024',
    overwrite=True,
    ignore=shutil.ignore_patterns('*.log', 'temp')
)

关键点说明:

  1. 使用copy2而不是copy可以保留文件元数据
  2. Path对象比字符串路径更安全易用
  3. dirs_exist_ok参数需要Python 3.8+
  4. 自定义ignore模式支持复杂过滤逻辑
  5. 完善的异常处理保证操作可靠性

这种方法可以处理以下复杂场景:

  • 混合文件类型(普通文件/符号链接/特殊文件)
  • 保留所有文件属性
  • 覆盖已有内容的安全处理
  • 灵活的过滤机制
  • 跨平台兼容性(Windows/Unix)
相关推荐
wewowilling2 分钟前
Coze智能体入门 --- AI Agent开发入门--第一章
python·低代码·agent·零代码·coze
Wx-bishekaifayuan5 分钟前
springboot公考微信小程序35511-计算机课程设计、毕业设计
spring boot·后端·python·django·课程设计·express·旅游
小猴子爱上树14 分钟前
跨马翻译:批量图片翻译+视频字幕+智能抠图,一站式跨境电商翻译工具
python·音视频
溪语流沙16 分钟前
【Web全栈进阶】OAuth实战——GitHub第三方登录
前端·python·github
计算机编程指导师19 分钟前
【计算机毕设选题】基于Hadoop的全球企业邮件安全合规数据可视化分析系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·数据分析·毕业设计·课程设计·企业邮件
SimonKing26 分钟前
零大模型依赖!SQLite FTS5 + jieba 打造纯本地知识库搜索
后端·python·程序员
慢云智慧空间26 分钟前
从智能终端到空间AI,慢云科技如何重新定义智慧人居?
人工智能·python·科技
yi01137 分钟前
LeetCode 3. 无重复字符的最长子串|不定长滑动窗口:什么时候更新最大值?
笔记·python·算法·leetcode·双指针·滑动窗口
2601_962885721 小时前
如何用 Python 计算索提诺比率和卡玛比率?
开发语言·python
小小张说故事1 小时前
Python 的描述符到底是个啥?property 和 classmethod 底层都靠它,3 个例子讲透
python