上传改卷压缩模式: 16MB流式切卷+逐卷7z+逐卷加密 (规避大文件OOM), 替代整文件7z

This commit is contained in:
lou
2026-08-10 20:36:12 +08:00
parent 9ddf325bec
commit d23f98b40d
+15 -26
View File
@@ -88,6 +88,7 @@ def cleanup_artifacts(path: str) -> None:
path + ".enc.part*",
path + ".init.json",
path + "_manifest.json",
path + ".chunk*", # 卷压缩模式产物 (逐卷加密文件)
):
for p in glob.glob(pattern):
try:
@@ -110,44 +111,32 @@ def upload() -> None:
server = "http://" + server # 只输 IP:端口 自动补协议
chunk_size = _clean(input("卷大小 MB [10]: ")) or "10"
# 已压缩格式 (正则匹配后缀) 跳过 7z 直传; 其余 7z 压缩
# 已压缩格式 (正则匹配后缀) 跳过 7z 直传; 其余走卷压缩模式
if not INCOMPRESSIBLE.search(path):
print("\n[1/3] 7z 压缩 (-mx=9) ...")
# 输出到磁盘目录 (/root 优先, Android 的 /tmp 是 tmpfs 内存盘, 大文件双份占内存会被杀);
# 非 root 环境回退临时目录 (PC 的 /tmp 在磁盘, 无此问题)
src7z_dir = "/root" if os.access("/root", os.W_OK) else tempfile.gettempdir()
src7z = os.path.join(src7z_dir, os.path.basename(path) + ".7z")
r = subprocess.run(["7z", "a", "-mx=9", "-bd", src7z, path])
if r.returncode != 0:
os.remove(src7z)
print(f"[错误] 7z 压缩失败 (exit {r.returncode})")
return
print(f"[1/3] 压缩完成: {os.path.getsize(path) / 1048576:.1f} MB -> {os.path.getsize(src7z) / 1048576:.1f} MB")
print("\n[1/3] 卷压缩: 16MB 流式切卷 + 逐卷 7z (mx=9) + 逐卷加密 ...")
code = run([
"metadata.py", path, "--chunk-size", chunk_size,
"--file-name", os.path.basename(path), "--vol-compress", "16",
])
else:
print(f"[1/3] 已压缩格式, 跳过 7z 直传")
src7z = path
print("\n[2/3] 加密 + 分卷 + 元数据 ...")
code = run([
"metadata.py", src7z, "--chunk-size", chunk_size,
"--file-name", os.path.basename(path), "--compressed",
])
print("[1/3] 已压缩格式, 跳过 7z 直传")
code = run([
"metadata.py", path, "--chunk-size", chunk_size,
"--file-name", os.path.basename(path),
])
if code != 0:
os.remove(src7z)
print("[失败] 加密/分卷失败")
return
print("\n[3/3] 上传 ...")
init_json = src7z + ".init.json"
manifest = src7z + "_manifest.json"
init_json = path + ".init.json"
manifest = path + "_manifest.json"
code = run(["transfer.py", "--server", server, "--init", init_json, "--manifest", manifest])
if code == 0:
print("[完成]")
cleanup_artifacts(src7z) # 清 .enc/.part/init/manifest
os.remove(src7z) # 清压缩临时文件
cleanup_artifacts(path) # 清 .enc/.part/init/manifest/卷文件
else:
print("[失败] 上传出错 (加密产物保留, 可续传)")
os.remove(src7z) # 压缩临时文件无续传价值, 清掉
def tasks() -> None: