python实现zip分卷压缩与解压

2022-12-21 16:52:55 浏览数 (1)

1. python实现zip分卷压缩

WinHex 开始16进制一个一个文件对比 WinRar 创建的分卷压缩和单个 zip 文件的差异。

如果想把单个大文件 test.zip -> 分卷文件 test.z01test.z02test.zip

首先,在创建的第一个分卷文件 test.z01的前面加上 x50x4bx07x08 这个是分卷压缩的文件头(header),占4个字节。其实单个压缩文件本身 header 就有这个了,而分卷压缩的需要两个emmm。之后便是从单个大压缩文件文件test.zip中读取 "一个分卷大小 -4 个字节"的数据,写入test.z01中,如何接着读取一个分卷大小的数据,写入test.z02,以此类推,最后一个分卷文件名也是test.zip

1.1 代码如下:

代码语言:javascript复制
import os
import zipfile


def zip_by_volume(file_path, block_size):
    """zip文件分卷压缩"""
    file_size = os.path.getsize(file_path)  # 文件字节数
    path, file_name = os.path.split(file_path)  # 除去文件名以外的path,文件名
    suffix = file_name.split('.')[-1]  # 文件后缀名
    # 添加到临时压缩文件
    zip_file = file_path   '.zip'
    with zipfile.ZipFile(zip_file, 'w') as zf:
        zf.write(file_path, arcname=file_name)
    # 小于分卷尺寸则直接返回压缩文件路径
    if file_size <= block_size:
        return zip_file
    else:
        fp = open(zip_file, 'rb')
        count = file_size // block_size   1
        # 创建分卷压缩文件的保存路径
        save_dir = path   os.sep   file_name   '_split'
        if os.path.exists(save_dir):
            from shutil import rmtree
            rmtree(save_dir)
        os.mkdir(save_dir)
        # 拆分压缩包为分卷文件
        for i in range(1, count   1):
            _suffix = 'z{:0>2}'.format(i) if i != count else 'zip'
            name = save_dir   os.sep   file_name.replace(str(suffix), _suffix)
            f = open(name, 'wb ')
            if i == 1:
                f.write(b'x50x4bx07x08')  # 添加分卷压缩header(4字节)
                f.write(fp.read(block_size - 4))
            else:
                f.write(fp.read(block_size))
        fp.close()
        os.remove(zip_file)     # 删除临时的 zip 文件   
        return save_dir


if __name__ == '__main__':
    file = r"D:Downloads1.mp4"        # 原始文件
    volume_size = 1024 * 1024 * 100  # 分卷大小 100MB
    path = zip_by_volume(file, volume_size)
    print(path)     # 输出分卷压缩文件的路径

 1.2 缺点:

该方法创建分卷压缩的时候,需要先在磁盘创建一个临时压缩包,然后将其拆分,实际上会对磁盘写入两次,这就浪费了时间。

当然,使用 ByteIO 进行字节流的压缩,但是这种方式需要先把文件读入内存,对于超级大的文件,这是不现实的,分分钟内存爆炸

2.解压

解压.ZIP分卷文件(亲测可用)

0 人点赞