Python 中如何复制文件?
Python 复制文件用标准库 shutil:copy() 复制内容和权限,copy2() 额外保留时间戳等元数据,copytree() 递归复制整个目录。本文对比各方法差异。
用标准库 shutil 模块:shutil.copy(src, dst) 复制文件;想尽量保留修改时间等受支持元数据用 shutil.copy2();复制整个目录树用 shutil.copytree()。
复制单个文件
import shutil
shutil.copy('/path/to/source/file', '/path/to/destination')
目标是目录时,文件会以原名复制进去;目标是文件路径时,会覆盖同名文件。
保留元数据:copy2
shutil.copy2('/path/to/source/file', '/path/to/destination')
copy2() 在复制内容之外,还尽量保留权限、修改时间、扩展属性等元数据。但所有者、ACL、备用数据流等并非所有平台都完整保留,不能把 copy2 当作完整备份保证;默认跟随符号链接,需按意图设置 follow_symlinks。
递归复制目录
shutil.copytree('/path/to/source/dir', '/path/to/dest/dir')
注意:目标目录必须不存在,否则抛 FileExistsError(Python 3.8+ 可加 dirs_exist_ok=True 允许合并,但同名文件仍可能被覆盖,不是只复制缺失文件)。
各函数对比
| 函数 | 复制内容 | 权限位 | 时间戳等元数据 |
|---|---|---|---|
copyfile() |
✓ | ✗ | ✗ |
copy() |
✓ | ✓ | ✗ |
copy2() |
✓ | ✓ | ✓ |
copytree() |
整个目录树 | ✓ | ✓ |
常见问题(FAQ)
Q:复制大文件时内存会不会爆?
A:通常不会把整个文件读入 Python 内存;实现可用内核快速复制或分块回退,但不保证所有平台固定缓冲或恒定总内存。
Q:跨平台路径怎么处理?
A:配合 pathlib.Path 或 os.path.join() 构造路径,避免手写斜杠。
Q:复制过程中出错能捕获吗?
A:可以,常见异常有 FileNotFoundError(源不存在)、PermissionError(无权限)、shutil.SameFileError(源和目标相同),用 try/except 分别处理;失败可能留下部分目标文件,复制也不保证原子性。