编写一个备份程序需要考虑多个方面,包括备份类型(完全备份和增量备份)、文件校验(如MD5值)、备份存储位置、备份时间戳、以及备份过程的异常处理等。以下是一个简单的Python备份程序示例,它实现了完全备份和增量备份,并包含了文件MD5值的校验:
```python
import os
import hashlib
import tarfile
import shutil
from datetime import datetime
def check_md5(fname):
"""计算文件的MD5值"""
m = hashlib.md5()
with open(fname, 'rb') as fobj:
while True:
data = fobj.read(4096)
if not data:
break
m.update(data)
return m.hexdigest()
def full_backup(src_dir, dst_dir, md5file):
"""执行完全备份,并更新MD5值文件"""
fname = os.path.basename(src_dir.rstrip(' / '))
backup_filename = f'{fname}_full_{datetime.now().strftime("%Y%m%d")}.tar.gz'
backup_path = os.path.join(dst_dir, backup_filename)
md5dict = {}
创建tar包
with tarfile.open(backup_path, 'w:gz') as tar:
tar.add(src_dir, arcname=fname)
计算源目录下所有文件的MD5值
for root, dirs, files in os.walk(src_dir):
for file in files:
file_path = os.path.join(root, file)
md5dict[file_path] = check_md5(file_path)
将MD5值写入文件
with open(md5file, 'w') as md5file:
for file_path, md5 in md5dict.items():
md5file.write(f'{file_path}:{md5}\n')
def incremental_backup(src_dir, dst_dir, last_backup_file):
"""执行增量备份,只备份变化的文件"""
last_backup_md5 = {}
if os.path.exists(last_backup_file):
with open(last_backup_file, 'r') as f:
for line in f:
path, md5 = line.strip().split(':')
last_backup_md5[path] = md5
获取当前时间,用作备份文件夹名
current_time = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_path = os.path.join(dst_dir, f'backup_{current_time}')
os.makedirs(backup_path, exist_ok=True)
遍历源目录,只备份变化或新增的文件
for root, dirs, files in os.walk(src_dir):
for file in files:
file_path = os.path.join(root, file)
if file_path not in last_backup_md5 or last_backup_md5[file_path] != check_md5(file_path):
复制文件到备份目录
shutil.copy2(file_path, backup_path)
更新MD5值
last_backup_md5[file_path] = check_md5(file_path)
将最新的MD5值写入文件
with open(last_backup_file, 'w') as md5file:
for file_path, md5 in last_backup_md5.items():
md5file.write(f'{file_path}:{md5}\n')
示例使用
if __name__ == "__main__":
source_directory = '/path/to/source'
destination_directory = '/path/to/destination'
full_backup_file = '/path/to/last_full_backup.md5'
incremental_backup_file = '/path/to/last_incremental_backup.md5'
执行完全备份
full_backup(source_directory, destination_directory, full_backup_file)
执行增量备份
incremental_backup(source_directory, destination_directory, incremental_backup_file)
```
备份程序说明
完全备份 (`full_backup`):
打包源目录下的所有内容