python分包压缩的方法
不懂python分包压缩的方法?其实想解决这个问题也不难,下面让小编带着大家一起学习怎么去解决,希望大家阅读完这篇文章后大所收获。
利用 Python 压缩 ZIP 文件,我们第一反应是使用 zipfile 库,然而,它的官方文档中却明确标注“此模块目前不能处理分卷 ZIP 文件”(⊙﹏⊙)
1、折腾经过:
翻遍了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。
2、Python3的代码实现:
importosimportzipfiledefzip_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'withzipfile.ZipFile(zip_file,'w')aszf:zf.write(file_path,arcname=file_name)#小于分卷尺寸则直接返回压缩文件路径iffile_size<=block_size:returnzip_fileelse:fp=open(zip_file,'rb')count=file_size//block_size+1#创建分卷压缩文件的保存路径save_dir=path+os.sep+file_name+'_split'ifos.path.exists(save_dir):fromshutilimportrmtreermtree(save_dir)os.mkdir(save_dir)#拆分压缩包为分卷文件foriinrange(1,count+1):_suffix='z{:0>2}'.format(i)ifi!=countelse'zip'name=save_dir+os.sep+file_name.replace(str(suffix),_suffix)f=open(name,'wb+')ifi==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文件returnsave_dirif__name__=='__main__':file=r"D:\Downloads\1.mp4"#原始文件volume_size=1024*1024*100#分卷大小100MBpath=zip_by_volume(file,volume_size)print(path)#输出分卷压缩文件的路径
3、缺点:
该方法创建分卷压缩的时候,需要先在磁盘创建一个临时压缩包,然后将其拆分,实际上会对磁盘写入两次,这就浪费了时间。
当然,我尝试使用 ByteIO 进行字节流的压缩,但是这种方式需要先把文件读入内存,对于超级大的文件,这是不现实的,分分钟内存爆炸。
然后,我尝试使用 io.pipe 的管道来处理,而 zipfile 压缩需要提供一个 file 或 file-like 对象,这个对象必须实现 seek() 和 tell() 方法来回去写入文件头信息,然而管道流没办法seek回去修改数据。这里,参考了Python zipfile + os.pipe()探索记,屏蔽了 seek() 和 tell() 函数。但是,后面我分卷时需要指定读取的字节数,这就需要这两个函数。。。我大概知道为什么 zipfile 库不支持创建分卷文件了〒▽〒
这个库的作者也没少掉头发。。。现在就将就一下,这样用着吧。。。
感谢你能够认真阅读完这篇文章,希望小编分享python分包压缩的方法内容对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,遇到问题就找亿速云,详细的解决方法等着你来学习!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。