我的知识记录

Python增量备份脚本:只复制有变化的文件省时间

用Python对比文件修改时间和大小实现增量备份,只复制新增或改动过的文件,大幅提升大目录备份速度。

场景痛点

全量备份一个几十GB的工作目录,每天都要复制一遍所有文件,硬盘读写耗时大。实际上绝大多数文件昨天没变过,只有几个新文件或修改过的文件需要备份。用Python对比源和目标的文件大小、修改时间,只复制差异部分,备份时间从几分钟降到几秒。

用到的库

shutil    # 标准库,复制文件
pathlib   # 标准库

完整代码

import shutil
from pathlib import Path


def needs_copy(src_file: Path, dst_file: Path) -> bool:
"""
判断源文件是否需要复制到目标
规则:目标不存在、大小不一致、修改时间更新,则需要复制
"""
if not dst_file.exists():
return True
src_stat = src_file.stat()
dst_stat = dst_file.stat()
if src_stat.st_size != dst_stat.st_size:
return True
# st_mtime 是修改时间戳,源比目标新就复制
if src_stat.st_mtime > dst_stat.st_mtime:
return True
return False


def incremental_backup(source_dir: str, target_dir: str) -> dict:
"""
增量备份:只复制新增或修改过的文件
"""
src = Path(source_dir).resolve()
dst = Path(target_dir).resolve()
dst.mkdir(parents=True, exist_ok=True)

stats = {"copied": 0, "unchanged": 0}

for file in src.rglob('*'):
if not file.is_file():
continue
rel_path = file.relative_to(src)
target_file = dst / rel_path

if needs_copy(file, target_file):
target_file.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(file, target_file)
stats["copied"] += 1
print(f"[复制] {rel_path}")
else:
stats["unchanged"] += 1

print(f"\n增量备份完成:新复制 {stats['copied']} 个,未变化 {stats['unchanged']} 个")
return stats


if __name__ == "__main__":
incremental_backup(
source_dir="./workspace",
target_dir="/backup/workspace"
)

代码讲解

  • needs_copy函数:三重判断。目标文件不存在直接复制;大小不同说明内容变了,复制;修改时间st_mtime源比目标新,说明被编辑过,复制。三个条件都不满足就跳过。
  • src_stat.st_mtime:文件最后修改时间的浮点时间戳,单位秒。跨文件系统比较时精度可能略有差异,但日常备份足够可靠。
  • 脚本不删除目标目录里源目录已不存在的文件。如果要做镜像同步(删除多余文件),需要额外反向遍历目标目录。
  • shutil.copy2:保留修改时间,下次再跑时对比st_mtime才有效。如果用copy()不保留时间戳,每次都会判定为需要复制。

运行结果

第一次运行会复制所有文件(全量)。第二次运行时,只有新增或修改过的文件会被复制,命令行打印[复制]标记的文件。大部分文件会显示为未变化

注意事项

  • st_mtime精度在FAT32等旧文件系统上是2秒,NTFS和ext4是纳秒级。跨盘备份时精度差异可能导致频繁复制同一文件,这种场景改用MD5哈希对比更稳,但计算量大。
  • 如果源文件正在被其他程序写入,读到的st_mtime可能不稳定,建议备份前关闭相关程序。
  • 增量备份不处理重命名:把文件从A文件夹移到B文件夹,脚本会把B里的当新文件复制,A里的旧文件仍留在目标目录。要做镜像同步需加删除逻辑。

Python增量备份脚本:只复制有变化的文件省时间

标签:

更新时间:2026-09-14 21:16:13

上一篇:Python遍历文件夹递归找文件:pathlib与os.walk两种写法

下一篇:Python获取文件大小修改时间:pathlib.stat详解