Python shutil模块完全指南:从基础到高级文件操作

liftword1个月前 (03-27)技术文章14

一、初识shutil:为什么需要它?

Python的os模块虽能处理基础文件操作,但在复杂场景下存在局限。shutil(Shell Utilities)提供更强大的文件管理功能,特别适合:

  • 批量处理:秒级复制整个目录结构
  • 数据备份:智能创建压缩存档
  • 项目部署:自动化文件分发
  • 跨平台:统一处理Windows/Linux路径
# 基础示例:复制文件并重命名
import shutil
shutil.copy('report.txt', 'backup/2023_report.txt')  # 自动创建目标目录

二、核心功能深度解析

1. 文件与目录复制

(1) 智能文件复制

def advanced_copy(src: str, dst: str) -> None:
    """
    高级文件复制(带元数据保留)
    
    参数:
        src: 源文件路径
        dst: 目标路径(支持目录或完整路径)
        
    特性:
         保留修改时间/权限
         自动创建目标目录
         支持跨设备复制
    """
    try:
        shutil.copy2(src, dst)  # 使用copy2保留元数据
        print(f" 复制成功:{src} → {dst}")
    except FileNotFoundError:
        print(f" 错误:源文件 {src} 不存在")
    except PermissionError:
        print(f" 权限不足:无法写入 {dst}")
    except shutil.SameFileError:  # 新增错误类型
        print(" 源文件和目标文件相同")

(2) 目录递归复制

def backup_project(src_dir: str, dest_dir: str) -> None:
    """
    项目备份(带过滤规则)
    
    过滤规则:
         忽略.tmp文件和__pycache__目录
         保留符号链接
         支持增量备份(dirs_exist_ok)
    """
    try:
        shutil.copytree(
            src_dir,
            f"{dest_dir}/backup",
            ignore=shutil.ignore_patterns('*.tmp', '__pycache__'),
            symlinks=True,
            dirs_exist_ok=True  # Python 3.8+支持
        )
        print(f" 项目备份完成:{dest_dir}")
    except shutil.Error as e:
        print(f" 备份错误:{e}")

2. 文件移动与删除

(1) 安全删除目录树

def delete_directory(path: str) -> None:
    """
    强制删除非空目录
    
    特性:
         自动处理只读文件(Windows)
         静默处理不存在的目录
    """
    def remove_readonly(func, path, _):
        "回调函数处理只读文件"
        os.chmod(path, stat.S_IWRITE)
        func(path)
        
    shutil.rmtree(
        path,
        ignore_errors=True,
        onerror=remove_readonly  # Windows专用处理
    )
    print(f" 目录已删除:{path}")

3. 压缩与解压

(1) 多格式压缩包创建

def create_archive(source_dir: str, output_path: str, format: str = "zip") -> None:
    """
    支持多种压缩格式
    
    参数:
        format: zip/tar/gztar/bztar/xztar
        
    示例:
        create_archive("docs", "backup/docs", "gztar")
        → 生成 docs.tar.gz
    """
    try:
        shutil.make_archive(
            base_name=output_path,
            format=format,
            root_dir=source_dir,
            base_dir='.'  # 压缩目录内容而非目录本身
        )
        print(f" 压缩包已创建:{output_path}.{format}")
    except shutil.ArchiveError as e:
        print(f" 压缩失败:{e}")

三、进阶工具与技巧

1. 磁盘空间监控

def check_disk_space(path: str) -> tuple[float, float, float]:
    """
    返回指定路径的磁盘空间(GB)
    
    返回值:
        (总空间, 已用空间, 剩余空间)
    """
    total, used, free = shutil.disk_usage(path)
    return (
        round(total/2**30, 1),
        round(used/2**30, 1),
        round(free/2**30, 1)
    )

2. 大文件分块复制

def copy_large_file(src: str, dst: str, buffer_size: int = 16*1024*1024) -> None:
    """
    高效复制大文件
    
    参数:
        buffer_size: 缓冲区大小(默认16MB)
    """
    try:
        with open(src, "rb") as fsrc, open(dst, "wb") as fdst:
            while chunk := fsrc.read(buffer_size):
                fdst.write(chunk)
                print(f"进度:{fdst.tell()/1024**2:.1f}MB", end="\r")
        print("\n 复制完成")
    except Exception as e:
        print(f"\n 复制失败:{e}")

四、综合案例:智能备份系统

import shutil
from pathlib import Path
from datetime import datetime

class BackupManager:
    """
    智能备份系统
    
    功能:
         自动清理旧备份
         支持排除特定文件
         生成操作日志
    """
    
    def __init__(self, project_dir: str, backup_root: str, keep_count: int = 5):
        self.project_dir = Path(project_dir)
        self.backup_root = Path(backup_root)
        self.keep_count = keep_count
        self.backup_root.mkdir(parents=True, exist_ok=True)
        
    def _generate_backup_name(self) -> str:
        """生成带时间戳的名称"""
        return f"backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
    
    def _clean_old_backups(self) -> None:
        """保留最近N个备份"""
        backups = sorted(
            self.backup_root.glob("backup_*.zip"),
            key=lambda f: f.stat().st_mtime,
            reverse=True
        )
        for old_backup in backups[self.keep_count:]:
            old_backup.unlink()
            print(f" 已删除旧备份:{old_backup.name}")
    
    def run(self) -> None:
        try:
            # 检查磁盘空间
            total, used, free = check_disk_space(self.backup_root)
            if free < 1.0:  # 保留至少1GB空间
                raise RuntimeError("磁盘空间不足")
                
            # 创建压缩包
            backup_name = self._generate_backup_name()
            shutil.make_archive(
                self.backup_root / backup_name,
                "zip",
                self.project_dir,
                ignore=shutil.ignore_patterns("*.log", "__pycache__")
            )
            
            # 清理旧备份
            self._clean_old_backups()
            print(" 备份成功完成!")
            
        except Exception as e:
            print(f" 备份失败:{e}")
            # 记录错误日志
            with open(self.backup_root / "errors.log", "a") as f:
                f.write(f"[{datetime.now()}] {str(e)}\n")

五、最佳实践指南

1. 路径处理规范

from pathlib import Path

# 跨平台路径拼接
project_dir = Path.home() / "projects" / "myapp"
backup_dir = Path("/mnt/backup") / "myapp"

# 路径验证
if not project_dir.exists():
    raise FileNotFoundError(f"目录不存在:{project_dir}")

2. 异常处理模板

def safe_operation():
    try:
        # 文件操作代码
        pass
    except (shutil.Error, OSError) as e:
        print(f" 操作失败:{e}")
        # 执行回滚操作
    except Exception as e:
        print(f" 未知错误:{e}")
        raise
    finally:
        # 释放资源
        pass

附录:功能对比表

功能

推荐函数

适用场景

特性

复制文件

copy2()

保留元数据

修改时间/权限

递归复制目录

copytree()

项目部署

支持过滤规则

删除目录树

rmtree()

清理临时文件

强制删除只读文件

创建压缩包

make_archive()

数据备份

支持ZIP/TAR等格式

磁盘监控

disk_usage()

空间预警

返回总/已用/剩余空间

相关文章

Python中的模块 (Module)和包 (Package)

Python的模块 (Module)和包 (Package)是Python程序中用于组织和封装代码的机制。模块是一个包含Python定义和语句的文件,也就是一个.py文件。包是一个包含多个模块的文件夹...

一分钟带你搞清楚Python模块、包、库

Python中的模块、包和库,很多新手小白经常搞混,别担心,看完这篇,保证你一分钟就能搞定!模块 (Module): 就好比是一块块乐高积木,每个模块包含特定的功能代码,比如实现加减乘除运算的模块。包...

17-1-Python-模块01

1-什么是模块模块是以.py结尾的一个Python代码文件,内含类、函数、变量等,我们可以导入进行使用。2-模块的作用Python中有很多各种不同的模块, 每一个模块都可以帮助我们快速的实现一些功能,...

脱颖而出的Python xlwings模块,一个更强大的操作Excel的模块

如下,在Python中存在很多支持Excel操作的第三方库,那么本文介绍的 xlwings 模块有其它模块有何区别呢?xrldxlwtopenpyxlxlswriterpandaswin32comxl...

Python强大的内置模块collections

1. 模块说明collections 是 Python 的一个内置模块,所谓内置模块的意思是指 Python 内部封装好的模块,无需安装即可直接使用。collections 包含了一些特殊的容器,针对...

Python进阶指南——掌握模块与包,打造高效代码库

倘若你期望在Python编程的领域中挥洒自如,那么对Python模块与包的运用展开深入的理解,无疑是至关重要的一个环节。今天,就让我们一同揭开Python模块与包的神秘面纱,让你的代码更加模块化、高效...