You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python zipfile压缩程序偶发自引用死循环导致体积无限增长问题

问题根因

核心逻辑漏洞是你把生成的压缩包直接放在了待压缩的目标目录下,结合两个场景触发偶发异常:

  1. 首次运行后目标目录下已经存在同名的myzipfile.zip文件,再次运行时_walk遍历会将历史压缩包纳入待压缩列表,新生成的压缩包会包含旧包,多次运行后体积会指数级膨胀
  2. 当待压缩目录文件数量极多、遍历耗时较长时,部分操作系统的文件写入缓存机制可能会让ZipFile初始化创建的空压缩包文件提前被目录遍历捕获,纳入待写入列表,后续写入时就会出现边读压缩包、边往压缩包里写的死循环,体积无限增长。

另外代码中_walk函数没有过滤特殊文件、也没有排除目标压缩包的逻辑,是触发问题的直接诱因。

修复方案
  • 优先将生成的压缩包输出路径改到待压缩目录之外,从根源避免被遍历到;如果必须放在当前目录,就遍历的时候主动排除目标压缩包文件
  • 调整逻辑顺序,先确认压缩包的绝对路径,执行目录遍历时直接过滤该文件
  • 删除冗余的zipf.close()调用,with上下文管理器会自动关闭压缩包文件

修复后代码如下:

import tkinter as tk
from tkinter import filedialog

from pathlib import Path
import zipfile
import os

root = tk.Tk()
root.withdraw()

file_path = filedialog.askdirectory()
# 直接用绝对路径处理,避免工作目录切换带来的混乱
target_dir = Path(file_path).resolve()

def _walk(path: Path, exclude_file: Path = None) -> list:
    all_files = []
    for x in path.iterdir():
        # 遍历过程主动排除目标压缩包文件
        if exclude_file is not None and x.resolve() == exclude_file:
            continue
        if x.is_dir():
            all_files.extend(_walk(x, exclude_file))
        else:
            all_files.append(x)
    return all_files


def zip_files(path: Path, archive_name: str):
    # 先拿到压缩包的绝对路径,如需放到待压缩目录外可改为 archive_path = path.parent / archive_name
    archive_path = (path / archive_name).resolve()
    all_files = _walk(path, exclude_file=archive_path)
    with zipfile.ZipFile(archive_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
        for f in all_files:
            # 指定arcname为相对路径,避免压缩包里出现多层冗余的绝对目录结构
            zipf.write(f, arcname=f.relative_to(path))


def zip_this_folder():
    print('compressing...')
    zip_files(target_dir, 'myzipfile.zip')
    print('...compression done!')


if __name__ == "__main__":
    zip_this_folder()

内容的提问来源于stack exchange,提问作者MM-13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 13:45:06