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