Python中如何并行压缩多个大文件到一个zip中?

有一批镜像,每个 1、2G 的样子,想并行压缩到一个 zip 中去。每次串行压缩实在太慢了。采用 zipfile 多进程压缩会有问题。求教


Python中如何并行压缩多个大文件到一个zip中?
1 回复

import zipfile
import concurrent.futures
import os
from pathlib import Path

def compress_file(file_path, zip_path):
    """压缩单个文件到zip包"""
    with zipfile.ZipFile(zip_path, 'a', compression=zipfile.ZIP_DEFLATED) as zf:
        zf.write(file_path, arcname=os.path.basename(file_path))

def parallel_compress(files_to_compress, output_zip, max_workers=4):
    """
    并行压缩多个文件
    
    Args:
        files_to_compress: 要压缩的文件路径列表
        output_zip: 输出的zip文件路径
        max_workers: 最大线程数
    """
    # 确保输出目录存在
    Path(output_zip).parent.mkdir(parents=True, exist_ok=True)
    
    # 先创建zip文件(如果已存在则清空)
    with zipfile.ZipFile(output_zip, 'w'):
        pass
    
    # 使用线程池并行压缩
    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
        # 提交所有压缩任务
        futures = [
            executor.submit(compress_file, file_path, output_zip)
            for file_path in files_to_compress
        ]
        
        # 等待所有任务完成
        for future in concurrent.futures.as_completed(futures):
            try:
                future.result()  # 获取结果,如果有异常会抛出
            except Exception as e:
                print(f"压缩文件时出错: {e}")

# 使用示例
if __name__ == "__main__":
    # 要压缩的文件列表
    files = [
        "large_file1.bin",
        "large_file2.bin", 
        "large_file3.bin"
    ]
    
    # 确保文件存在
    files = [f for f in files if os.path.exists(f)]
    
    if files:
        parallel_compress(
            files_to_compress=files,
            output_zip="compressed_files.zip",
            max_workers=4  # 根据CPU核心数调整
        )
        print(f"已压缩 {len(files)} 个文件到 compressed_files.zip")
    else:
        print("未找到要压缩的文件")

核心要点:

  1. ThreadPoolExecutor实现并行压缩,I/O密集型任务用线程池正合适
  2. 每个线程独立压缩一个文件到同一个zip包
  3. ZipFile'a'追加模式避免文件覆盖
  4. 先创建空zip文件确保后续追加操作正常

注意:多线程写zip时,zip库内部会处理同步,但大量小文件可能不如批量压缩快。

回到顶部