Python3实现zip分卷压缩过程解析

 更新时间:2019年10月09日 08:31:43   作者:zaxtyson   我要评论
这篇文章主要介绍了Python3实现zip分卷压缩过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

使用zipfile库

查看 官方中文文档

利用 Python 压缩 ZIP 文件,我们第一反应是使用 zipfile 库,然而,它的官方文档中却明确标注“此模块目前不能处理分卷 ZIP 文件”,(⊙﹏⊙)

折腾经过

翻遍了Google、CSDN、Stackoverflow等平台均未找到解决方案,最靠谱的是调用外部解压程序实现分卷压缩的功能。但是,如何不依靠外部程序实现这个功能呢??

于是乎,只能自己慢慢造轮子。看着 ZIP 格式开发商留下的文档 ZIP File Format Specification,头疼啊(;´д`)。于是我拿着 WinHex 开始16进制一个一个文件对比 WinRar 创建的分卷压缩和单个 zip 文件的差异。最后还真的整出来了( ̄▽ ̄)"

如果想把单个大文件 test.zip -> 分卷文件 test.z01、test.z02、test.zip

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

Python3的代码实现

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'\x50\x4b\x07\x08') # 添加分卷压缩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:\Downloads\1.mp4"    # 原始文件
  volume_size = 1024 * 1024 * 100 # 分卷大小 100MB
  path = zip_by_volume(file, volume_size)
  print(path)   # 输出分卷压缩文件的路径

缺点

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

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

然后,我尝试使用 io.pipe 的管道来处理,而 zipfile 压缩需要提供一个 file 或 file-like 对象,这个对象必须实现 seek() 和 tell() 方法来回去写入文件头信息,然而管道流没办法seek回去修改数据。这里,参考了Python zipfile + os.pipe()探索记,屏蔽了 seek() 和 tell() 函数。但是,后面我分卷时需要指定读取的字节数,这就需要这两个函数。。。我大概知道为什么 zipfile 库不支持创建分卷文件了〒▽〒

这个库的作者也没少掉头发。。。现在就将就一下,这样用着吧。。。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持澳门金沙网上娱乐。

相关文章

  • 今天 平安夜 Python 送你一顶圣诞帽 @微信官方

    今天 平安夜 Python 送你一顶圣诞帽 @微信官方

    昨晚我的朋友圈是这样的:请给我一个圣诞帽@微信官方。好吧,看看python是怎么搞到圣诞帽的。下面跟随小编一起看看吧
    2017-12-12
  • Python3.6通过自带的urllib通过get或post方法请求url的实例

    Python3.6通过自带的urllib通过get或post方法请求url的实例

    下面小编就为大家分享一篇Python3.6通过自带的urllib通过get或post方法请求url的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • 利用python获取某年中每个月的第一天和最后一天

    利用python获取某年中每个月的第一天和最后一天

    最近在做项目的时候,突然想到的这个问题,觉得比较有趣,就实际测试了一下,考虑到以后可能会有用,就总结下来写了这篇文章,刚兴趣的朋友们可以参考学习下,下面来跟着小编一起看看吧。
    2016-12-12
  • python调用Delphi写的Dll代码示例

    python调用Delphi写的Dll代码示例

    这篇文章主要介绍了python调用Delphi写的Dll代码示例,具有一定参考价值,需要的朋友可以了解下。
    2017-12-12
  • Python正则简单实例分析

    Python正则简单实例分析

    这篇文章主要介绍了Python正则简单实例,具体分析了Python针对字符串的简单正则匹配测试中遇到的问题与相关注意事项,需要的朋友可以参考下
    2017-03-03
  • Python爬虫抓取代理IP并检验可用性的实例

    Python爬虫抓取代理IP并检验可用性的实例

    今天小编就为大家分享一篇Python爬虫抓取代理IP并检验可用性的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • Python深拷贝与浅拷贝用法实例分析

    Python深拷贝与浅拷贝用法实例分析

    这篇文章主要介绍了Python深拷贝与浅拷贝用法,结合实例形式分析了Python对象的复制、深拷贝、浅拷贝等操作原理、用法及相关注意事项,需要的朋友可以参考下
    2019-05-05
  • Django中login_required装饰器的深入介绍

    Django中login_required装饰器的深入介绍

    这篇文章主要给大家介绍了关于Django中login_required装饰器的使用方法,并给大家进行了实例借鉴,利用@login_required实现Django用户登陆访问限制,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-11-11
  • 详解Python数据分析--Pandas知识点

    详解Python数据分析--Pandas知识点

    这篇文章主要介绍了Python数据分析--Pandas知识点,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • TensorFLow用Saver保存和恢复变量

    TensorFLow用Saver保存和恢复变量

    这篇文章主要为大家详细介绍了TensorFLow用Saver保存和恢复变量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03

最新评论