繁星骤变|

天才俱乐部

园龄:2年6个月随笔:100阅读:22994

Python 实现 zip 分卷解压

在上传数据备份到云端的时候,由于数据文件过大,可能会遇到各种各样的问题:

比如 49G 的大文件 git lfs push 到 99% 突然失败,你说心态爆炸不爆炸?

再比如某些网盘会限制单个文件上传大小限制在 4G 以内;

因此我们可能会用7z之类的压缩软件对数据文件进行分卷压缩,得到多个分卷文件,例如下面的例子:

将歌词文件夹 lyrics 压缩成6个分卷,后缀为 *.zip.00* 的格式。用鼠标操作解压这种多个分卷文件很容易,操作如下图所示:

然而有时候我们需要实现数据下载+解压的自动化,比如将数据集集成到 datasets 之类的 pypi 的 API,就需要对云端下载下来的 zip 分卷文件用代码实现解压。下面我们来提供在 python 下实现 zip 分卷解压的解决方案:

import os
import re
import zipfile
from tqdm import tqdm


def sort_files_by_extension(files):
    def key_function(file_path):
        # 获取文件路径的后缀名,以数字作为排序键
        return int(file_path.split('.')[-1])

    # 使用自定义的排序函数进行排序
    sorted_files = sorted(files, key=key_function)
    return sorted_files


def get_files_with_order(folder_path):
    files = []
    for file_name in os.listdir(folder_path):
        if re.match(r'.+\.zip\.\d{3}$', file_name):
            files.append(os.path.join(folder_path, file_name))

    return sort_files_by_extension(files)


def merge_files(input_files, output_file):
    with open(output_file, 'wb') as merged_file:
        for input_file in tqdm(input_files, desc="Merging..."):
            with open(input_file, 'rb') as f:
                merged_file.write(f.read())


def extract_zip(zip_file, extract_dir):
    # 确保目标目录存在
    os.makedirs(extract_dir, exist_ok=True)

    # 获取ZIP文件中的文件总数
    with zipfile.ZipFile(zip_file) as zip_ref:
        total_files = len(zip_ref.infolist())

        # 使用tqdm显示进度条
        with tqdm(total=total_files, desc='Extracting...', unit='file') as pbar:
            # 解压每个文件
            for file in zip_ref.infolist():
                zip_ref.extract(file, extract_dir)
                pbar.update(1)


def extract_multi_vol_zip(input_dir='folder_containing_vols', output_dir='outdir'):
    tmp_file = 'merged.zip'
    input_files = get_files_with_order(input_dir)
    merge_files(input_files, tmp_file)
    extract_zip(tmp_file, output_dir)
    os.remove(tmp_file)


extract_multi_vol_zip()

其中 folder_containing_vols 便是包含所有分卷文件的文件夹,outdir为导出解压结果的目标路径。其核心原理是:先将分卷文件按照后缀名序号顺序以字节流首尾相连,合并成单个 merge.zip 文件,后面再按照常规的解压单个 .zip 文件的方法提取压缩包。我们分别在合并文件流与解压步骤中添加了进度条,以便直观查看进度。

本文作者:天才俱乐部

本文链接:https://www.cnblogs.com/Genius-Society/p/17993064

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。若有侵权请联系作者。

posted @   天才俱乐部  阅读(325)  评论(0编辑  收藏 
(评论功能已被禁用)
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起