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

使用zipfile模块压缩文件体积异常增大问题求助

问题分析与解决方案

核心问题

你的代码存在重复执行压缩逻辑的严重错误,直接导致首个压缩文件被反复追加写入,最终体积无限制膨胀:

  • copy_move_files函数外层有for file_path in file_paths:循环,而file_paths是source_folder下所有文件/文件夹的集合
  • 当action == "just_zip"时,每一次循环都会重新执行目录扫描、文件收集,然后将相同文件重复添加到同一个zip包
  • 原文件总大小仅90MB,但每次循环都会把文件再打包一次,最终zip体积持续暴涨至120GB以上

修复方案

将just_zip的逻辑从外层循环中剥离,只执行一次扫描和压缩操作,彻底避免重复写入问题。

修改后的代码片段

def copy_move_files(self, file_paths, action):
    third_input = self.get_third_input()

    # 单独处理just_zip逻辑,跳过外层循环
    if action == "just_zip":
        file_paths_to_zip = []
        file_paths_to_delete = []
        source_with_third = os.path.join(self.source_folder, third_input)

        pattern = r'\d{8}_\d{6}_\d{14}'

        for root, _, files in os.walk(source_with_third):
            for file in files:
                file_name = os.path.basename(file)
                file_path = os.path.join(root, file)
                if re.match(pattern, file_name):
                    file_paths_to_zip.append(file_path)
                file_paths_to_delete.append(file_path)

        # 按前缀分组,将同前缀文件打包到同一个zip
        zip_groups = {}
        for file_path in file_paths_to_zip:
            prefix = os.path.basename(file_path)[:30]
            zip_path = os.path.join(os.path.dirname(file_path), f'{prefix}.zip')
            if zip_path not in zip_groups:
                zip_groups[zip_path] = []
            zip_groups[zip_path].append(file_path)

        # 一次性写入分组内所有文件到对应zip
        for zip_path, files_to_add in zip_groups.items():
            try:
                # 使用'w'模式创建新zip,避免追加重复内容
                with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
                    for file_path in files_to_add:
                        arcname = os.path.basename(file_path)
                        zipf.write(file_path, arcname)
                self.logger.info("Zip %s创建成功,包含%d个文件", zip_path, len(files_to_add))
            except Exception as e:
                self.logger.error("创建Zip %s失败:%s", zip_path, str(e))

        # 删除非zip文件
        for file_path in file_paths_to_delete:
            if not file_path.endswith(".zip"):
                try:
                    os.remove(file_path)
                    self.logger.info("文件%s删除成功", os.path.basename(file_path))
                except Exception as e:
                    self.logger.error("删除文件%s失败:%s", os.path.basename(file_path), str(e))

        self.logger.info("%s下文件压缩完成", self.source_folder)
        return  # 直接返回,不执行后续copy/move的循环逻辑

    # 以下为原有的copy/move逻辑
    for file_path in file_paths:
        if action == "copy":
            # .....
        elif action == "move":
            # .....

关键修改点

  1. 剥离just_zip逻辑:将压缩代码移到外层循环之前,执行完成后直接返回,彻底避免重复执行
  2. 按前缀分组打包:解决原逻辑中每个文件单独创建同前缀zip、导致重复写入的问题,将同前缀文件一次性打包
  3. 使用'w'模式创建zip:确保每次生成全新的zip文件,不会追加重复内容;之前用'a'模式是持续往同一个zip中添加重复文件的核心原因
  4. 完善异常处理:删除文件时加入异常捕获,避免因文件已被删除导致程序崩溃

补充说明

  • 你之前尝试用'w'模式没生成文件,大概率是路径错误或没有匹配到目标文件,而非模式本身问题
  • 线程不是问题根源,逻辑重复执行才是zip体积膨胀的核心原因

内容的提问来源于stack exchange,提问作者Icerewl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:25:54