forked from lioensky/VCPToolBox
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackup_vcp.py
More file actions
82 lines (63 loc) · 3.11 KB
/
Copy pathbackup_vcp.py
File metadata and controls
82 lines (63 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import os
import zipfile
import datetime
import sys
def backup_user_data_fast(backup_filename):
"""
极速版本 - 带智能进度条
"""
file_extensions = {'.txt', '.md', '.env', '.json'}
excluded_dirs = {'.git', '__pycache__', 'node_modules', '.venv', 'venv'}
excluded_paths = {os.path.normpath('dailynote/MusicDiary')}
source_dir = '.'
print("阶段1: 扫描文件...")
start_time = datetime.datetime.now()
# 第一阶段:快速收集所有文件路径
files_to_backup = []
for root, dirs, files in os.walk(source_dir):
root_norm = os.path.normpath(root)
dirs[:] = [d for d in dirs
if d not in excluded_dirs
and os.path.join(root_norm, d) not in excluded_paths]
for file in files:
_, ext = os.path.splitext(file)
if ext in file_extensions:
file_path = os.path.join(root, file)
if not (file == backup_filename and root in ('.', './')):
files_to_backup.append(file_path)
scan_time = (datetime.datetime.now() - start_time).total_seconds()
print(f"扫描完成: {len(files_to_backup):,} 个文件, 耗时 {scan_time:.2f}s")
# 第二阶段:压缩文件(带智能进度条)
print("阶段2: 压缩文件...")
compress_start = datetime.datetime.now()
total = len(files_to_backup)
# ✅ 动态计算更新频率:至少更新20次,但不超过每个文件都更新
update_interval = max(1, total // 20)
with zipfile.ZipFile(backup_filename, 'w', zipfile.ZIP_DEFLATED,
compresslevel=1) as zipf:
for i, file_path in enumerate(files_to_backup):
try:
zipf.write(file_path, os.path.relpath(file_path, source_dir))
except (PermissionError, FileNotFoundError):
pass
# ✅ 智能进度更新
if (i + 1) % update_interval == 0 or (i + 1) == total:
pct = (i + 1) / total * 100
bar_len = 30
filled = int(bar_len * (i + 1) // total)
bar = '█' * filled + '░' * (bar_len - filled)
elapsed = (datetime.datetime.now() - compress_start).total_seconds()
speed = (i + 1) / elapsed if elapsed > 0 else 0
sys.stdout.write(f"\r[{bar}] {pct:5.1f}% | {i+1:,}/{total:,} | {speed:.0f} 文件/秒")
sys.stdout.flush()
print() # 换行
total_time = (datetime.datetime.now() - start_time).total_seconds()
backup_size = os.path.getsize(backup_filename) / (1024 * 1024)
print(f"{'=' * 50}")
print(f"✅ 备份完成: {backup_filename}")
print(f"📁 文件数量: {total:,}")
print(f"📦 大小: {backup_size:.2f} MB")
print(f"⏱️ 总耗时: {total_time:.2f}s")
if __name__ == "__main__":
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
backup_user_data_fast(f"backup_{timestamp}.zip")