shutil 标准库: Python 文件操作的万用刀
shutil 标准库: Python 文件操作的万用刀
今天来聊一个被低估的 Python 标准库 - shutil 。工作中我们用 Python (尤其是写一些短小轻快的脚本)虽然经常和文件打交道,却很少用到 shutil 。但实际上, shutil 提供了比 os 模块更高级的文件操作接口,能让我们写出更 Pythonic 的代码。从一个真实场景说起最近在整理项目代码时,需要将散落在各处的配置
shutil 标准库: Python 文件操作的万用刀
今天来聊一个被低估的 Python 标准库 - shutil
。工作中我们用 Python (尤其是写一些短小轻快的脚本)虽然经常和文件打交道,却很少用到 shutil
。但实际上, shutil
提供了比 os
模块更高级的文件操作接口,能让我们写出更 Pythonic 的代码。
最近在整理项目代码时,需要将散落在各处的配置文件归类到统一目录。按以往的习惯,我会这样写:
代码语言:python代码运行次数:0运行复制import os
# 创建目标目录
if not os.("configs"):
("configs")
# 移动文件
for root, dirs, files in os.walk("."):
for file in files:
if (".conf"):
src = os.path.join(root, file)
dst = os.path.join("configs", file)
os.rename(src, dst)
这段代码能完成任务,但存在几个问题:
- 如果目标路径已存在同名文件会报错
- 不支持跨设备移动
- 没有保留文件的元数据(权限、时间戳等)
用 shutil 可以优雅地解决这些问题:
代码语言:python代码运行次数:0运行复制import shutil
import os
("configs", exist_ok=True)
for root, dirs, files in os.walk("."):
for file in files:
if (".conf"):
src = os.path.join(root, file)
dst = os.path.join("configs", file)
(src, dst)
看起来差别不大,但 ()
会:
- 当目标路径已存在同名文件时,
()
的行为取决于操作系统- Windows: 如果目标文件存在且正在使用,会抛出
PermissionError
;否则会静默覆盖目标文件 - Unix/Linux: 会遵循操作系统的规则。如果用户有权限,会覆盖目标文件;否则抛出
PermissionError
- Windows: 如果目标文件存在且正在使用,会抛出
- 支持跨设备移动
- "跨设备"指的是在不同的文件系统或存储设备之间移动文件,比如从 C 盘移动到 D 盘、从本地磁盘移动到网络驱动器、从固态硬盘移动到 U 盘
()
会首先尝试使用os.rename()
,如果失败且错误是跨设备错误errno.EXDEV
,则复制文件到目标位置,验证复制成功,最后删除源文件
- 保留源文件的所有元数据
1. 复制文件和目录
代码语言:python代码运行次数:0运行复制# 复制文件
("", "") # 复制文件内容
2("", "") # 复制文件内容和元数据
# 复制目录
tree("src_dir", "dst_dir") # 递归复制整个目录树
copy2() 比 copy() 多了preserving metadata 的功能,在需要保留文件属性时很有用。
2. 删除目录
代码语言:python代码运行次数:0运行复制# 删除目录树
shutil.rmtree("dir_to_remove") # 递归删除目录及其内容
比 os.rmdir()
强大,后者只能删除空目录。
. 磁盘使用统计
代码语言:python代码运行次数:0运行复制total, used, free = shutil.disk_usage(".")
print(f"总空间: {total // (2**0)} GiB")
print(f"已使用: {used // (2**0)} GiB")
print(f"可用: {free // (2**0)} GiB")
直观地获取磁盘使用情况,免去了手动计算的麻烦。
4. 文件打包与压缩
代码语言:python代码运行次数:0运行复制# 创建压缩包
_archive("backup", "zip", "source_dir") # 支持zip、tar等格式
# 解压缩
shutil.unpack_archive("backup.zip", "extract_dir")
1. 项目备份工具
代码语言:python代码运行次数:0运行复制import shutil
from datetime import datetime
import os
def backup_project(project_path, backup_dir="backups"):
# 创建以时间戳命名的备份文件
timestamp = ().strftime("%Y%m%d_%H%M%S")
backup_name = f"backup_{timestamp}"
# 确保备份目录存在
(backup_dir, exist_ok=True)
# 创建压缩包
archive_path = _archive(
os.path.join(backup_dir, backup_name),
"zip",
project_path
)
print(f"备份完成: {archive_path}")
2. 大文件搬运工具
代码语言:python代码运行次数:0运行复制import shutil
import os
from pathlib import Path
def move_large_files(src_dir, dst_dir, min_size_mb=100):
"""移动大于指定大小的文件到目标目录"""
dst_path = Path(dst_dir)
dst_(exist_ok=True)
for root, _, files in os.walk(src_dir):
for file in files:
file_path = Path(root) / file
if file_path.stat().st_size > min_size_mb * 1024 * 1024:
try:
(str(file_path), dst_path / file)
print(f"已移动: {file}")
except Exception as e:
print(f"移动失败 {file}: {e}")
. 智能文件分类器
代码语言:python代码运行次数:0运行复制import shutil
from pathlib import Path
import mimetypes
def organize_files(directory):
"""根据文件类型自动分类文件"""
directory = Path(directory)
# 遍历所有文件
for file_path in directory.rglob("*"):
if file_path.is_file():
# 获取文件类型
mime_type, _ = mimetypes.guess_type(str(file_path))
if mime_type:
category = mime_type.split("/")[0]
# 创建分类目录
dest_dir = directory / category
dest_(exist_ok=True)
# 移动文件
try:
(str(file_path), str(dest_dir / file_))
except Exception as e:
print(f"处理{file_path}时出错: {e}")
- 对于大文件操作,shutil 提供了 copyfileobj() 方法,支持设置缓冲区大小:
with open("source.dat", "rb") as fsrc:
with open("dest.dat", "wb") as fdst:
fileobj(fsrc, fdst, length=1024*1024) # 1MB buffer
- copytree() 支持多进程并行复制:
from multiprocessing import Pool
def copy_with_progress(src, dst):
2(src, dst)
return dst
with Pool(processes=4) as pool:
tree("src_dir", "dst_dir", copy_function=)
1. 权限和所有权
代码语言:python代码运行次数:0运行复制import shutil
import os
def mirror_permissi(src, dst):
# 复制权限位
mode(src, dst)
# 复制所有权(需要root权限)
try:
(dst,
user=os.stat(src).st_uid,
group=os.stat(src).st_gid)
except PermissionError:
print("需要管理员权限来修改所有权")
2. 元数据复制
代码语言:python代码运行次数:0运行复制import shutil
import os
from datetime import datetime
def show_metadata(path):
stat = os.stat(path)
print(f"访问时间: {datetime.fromtimestamp(stat.st_atime)}")
print(f"修改时间: {datetime.fromtimestamp(stat.st_mtime)}")
print(f"创建时间: {datetime.fromtimestamp(stat.st_ctime)}")
print(f"权限: {oct(stat.st_mode)[-:]}")
print(f"大小: {stat.st_size} bytes")
# 复制文件并保留所有元数据
src = ""
dst = ""
2(src, dst)
print("源文件元数据:")
show_metadata(src)
print("\n目标文件元数据:")
show_metadata(dst)
shutil
是一个设计优雅的文件操作库:
- 提供了比 os 模块更高级的接口
- 自动处理各种边界情况
- 保持了 Python "batteries included" 的理念
下次遇到文件操作需求,不妨先看看 shutil 是否已经提供了合适的工具。毕竟,"不要重复发明轮子"也是 Python 的哲学之一。
希望这篇文章对你有帮助!如果觉得有用,欢迎点赞转发~
#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
上传时间: 2025-07-26 12:25:45
推荐阅读
留言与评论(共有 6 条评论) |
本站网友 财气网 | 19分钟前 发表 |
却很少用到 shutil | |
本站网友 郑宇民 | 27分钟前 发表 |
"dst_dir" | |
本站网友 环亚汇市 | 12分钟前 发表 |
dst) | |
本站网友 4月份汽车销量 | 4分钟前 发表 |
if (".conf") | |
本站网友 xess | 29分钟前 发表 |
used |