一、本文编写缘由

在之前写的《python 爬取p站排行榜并自动发送邮件》中涉及到把插画原图文件夹整体打包压缩,然后以附件的形式进行邮件转发。但是一般来说,原图的尺寸都会比较大,且对于图片来说,能够做到的无失真压缩很小,压缩之后基本跟原始大小差不多。而大文件的传输将耗费比较长的时间,如果中止可能整个文件的传送被取消,且邮件对与附件的大小作了要求,要求上传规定范围内的文件。因此,有了将一个文件压缩成多个文件的需求。

二、zipfile模块介绍

zipfile模块用于读写ZIP文件。使用python进行压缩的简单步骤如下:

  • 导包:import zipfile
  • 创建zipfile对象:zip_obj = zipfile.ZipFile()
  • 写压缩文件:zip_obj.write()

在第二步中,通过zipfile.ZipFile()实例化zipfile对象,该方法的参数如下:

ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=True,compresslevel=None)
  • file:文件的路径或者一个类似文件的对象。如果是前者,那么这个文件将会被ZipFile对象打开和关闭。
  • mode:读模式"r",写模式“w”,新建模式“x”,追加模式“a”
  • compression:存储模式不压缩“ZIP_STORED”,只存储不压缩;默认压缩模式“ZIP_DEFLATED”,使用gzip算法进行压缩;压缩模式“ZIP_BZIP2”,使用bzip2算法进行压缩;压缩模式“ZIP_LZMA ”,使用lzma模式进行压缩。
  • allowZip64:如果值为True,表示支持64位的压缩,一般而言,在要压缩的文件大于2G时,会用到这个选项。默认情况下,该值为False,因为unix系统不支持。
  • compresslevel:为空或者一个整数,指定传送到压缩器的级别。当使用ZIP_STORED或者ZIP_LZMA没有影响;当使用ZIP_DEFLATED时,接受0~9;当使用ZIP_BZIP2时,接受1~9。

三、单个文件压缩

根据上文提到的使用python进行zip文件压缩步骤,对当前目录下的"res_data.json"文件进行压缩,代码实现如下:

# step 1: 导包
import zipfile
import os# 指定要压缩的文件及压缩后的文件名称
zip_file = 'res_data.json'
zip_file_new = zip_file+'.zip'
# 如果文件存在
if not os.path.exists(zip_file):print('您要压缩的文件不存在!')
else:# step 2: 实例化zipfile对象zip = zipfile.ZipFile(zip_file_new, 'w', zipfile.ZIP_DEFLATED)# step 3: 写压缩文件zip.write(zip_file)print('文件压缩成功!')

执行zip = zipfile.ZipFile(zip_file_new, 'w', zipfile.ZIP_DEFLATED)在当前目录下生成压缩文件res_data.json.zip,如下图。不管是否存在要压缩的文件,所以在执行这条语句时增加了一个条件判断,判断给的文件路径是否存在:

四、单个目录压缩

1、压缩单个目录

对一个包含文件不包含目录的文件夹(目录)进行压缩,需要对文件夹中的所有文件进行遍历,然后逐一写入到压缩文件中。这里通过for循环遍历指定文件目录下的所有文件名,然后对文件目录下的文件进行路径拼接,最后通过zipfile的write方法写入压缩文件。具体实现如下:

import zipfile
import os# 指定目录路径及压缩文件名称
dir_name = 'test_dir'
zip_file = dir_name+'.zip'if not os.path.exists(dir_name):                # 如果目录路径不存在print('您要压缩的目录不存在')
else:                                           # 否则压缩目录zip = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED)for item in os.listdir(dir_name):zip.write(dir_name+os.sep+item)zip.close()print('目录压缩成功')

以上代码可以实现对目录中的所有文件进行压缩。但是,如果目录中含有目录,那么不会自动该目录中的内容到压缩文件中,而仅仅往压缩文件中添加压缩目录下的文件。如下图,在test_dir目录下存在一个sub_dir目录,且目录下的两个文件内容不为空:

经过执行上面代码进行压缩,由下图可知,对目录中的文件没有进行压缩,其大小为0 bytes。

2、单个目录压缩优化1

上述对目录进行压缩的代码,仅仅对一级目录下的所有item进行遍历,而没有对指定压缩目录下的目录,甚至该目录下三级、四级目录中的文件进行写入压缩文件。因此,为了对一个目录进行完整压缩,将里面所有的文件信息添加到压缩文件中,需要增加对于目录下item的判断以及子目录的遍历。

# 导包
import zipfile
import os# 指定目录路径及压缩文件名称
dir_name = 'test_dir'
zip_file = dir_name+'.zip'# 如果目录路径不存在
if not os.path.exists(dir_name):print('您要压缩的目录不存在')
else:               # 否则压缩目录zip = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED)zip_test(zip, dir_name)zip.closeprint('目录压缩成功')def zip_test(zip, name):for item in os.listdir(name):file_path = name+os.sep+itemzip.write(file_path)if os.path.isdir(file_path):zip_test(zip, file_path)

以上代码以函数递归调用的方式对目录进行深度优先遍历,如果当前item是目录,那么记录该目录路径并写入压缩文件,然后对该目录进行遍历,从而对实现对整个目录文件的遍历。运行成功后获得压缩文件,小大为877bytes,sub_dir目录大小不为0,且可以显示内部文件,如下图:

3、单个目录压缩优化2

python的os模块提供了一个简单易用的文件目录遍历器“os.walk()”,通过在目录树中向上或者向下游走,输出目录中的文件名。其语法格式为:os.walk(top, topdown=True, οnerrοr=None, followlinks=False),其中top表示所要遍历目录的地址。该方法返回一个三元组(root, dirs, files),root表示正在遍历文件夹本身的地址,dirs表示遍历目录下的一级目录列表,files表示遍历目录的文件列表。通过该方法对整个目录进行遍历并写入压缩文件,代码实现如下:

import zipfile
import osmonth_rank_dir = "test_dir"
zip_file_new = month_rank_dir+'.zip'
if os.path.exists(month_rank_dir):print('正在为您压缩...')# 压缩后的名字zip = zipfile.ZipFile(zip_file_new, 'w', zipfile.ZIP_DEFLATED)for dir_path, dir_names, file_names in os.walk(month_rank_dir):# 去掉目标跟路径,只对目标文件夹下面的文件及文件夹进行压缩fpath = dir_path.replace(month_rank_dir, '')for filename in file_names:zip.write(os.path.join(dir_path, filename), os.path.join(fpath, filename))zip.close()print('该目录压缩成功!')
else:print('您要压缩的目录不存在...')

运行结果如下,文件夹中的所有文件被添加到压缩文件中,被压缩后整体大小为677bytes,比上述方法减少了100 bytes。

五、目录多对一压缩

有时候,可能并不想完全压缩一整个目录,仅仅像打包压缩其中的一部分,那么可以将这一部分想要一起打包压缩的文件目录添加到列表中,以参数的方式传给封装的方法进行压缩。只需要增加一个for循环遍历目录列表即可。代码实现如下:

import os
import zipfiledef zipdirs(dir_list):zip_file = 'test.zip'# 压缩后的名字zip = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED)for dir in dir_list:if os.path.exists(dir):print('正在为您压缩%s...' % dir)for dir_path, dir_names, file_names in os.walk(dir):# 去掉目标跟路径,只对目标文件夹下面的文件及文件夹进行压缩fpath = dir_path.replace(dir, '')for filename in file_names:zip.write(os.path.join(dir_path, filename), os.path.join(fpath, filename))print('%s目录压缩成功!' % dir)else:print('您要压缩的目录不存在...')zip.close()

上述代码实现了对指定的多个文件目录进行压缩,但是这些目录中的文件都将会压缩到一个目录下。可以通过先创建一个目录,将指定目录列表中的文件目录添加到新创建的目录中,然后打包压缩新创建的目录,最后删除新创建的目录即可。代码如下:

import os
import zipfiledef zipdirs(dir_list):# 指定一个压缩目录及压缩文件zip_dir = 'test'zip_file = zip_dir+'.zip'zip = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED)# 如果压缩目录不存在那么创建if not os.path.exists(zip_dir):os.mkdir(zip_dir)# 将目录列表添加到该目录下addtodir(dir_list, zip_dir)print('正在为您压缩...')for dir_path, dir_names, file_names in os.walk(zip_dir):# 去掉目标跟路径,只对目标文件夹下面的文件及文件夹进行压缩fpath = dir_path.replace(dir, '')for filename in file_names:zip.write(os.path.join(dir_path, filename), os.path.join(fpath, filename))print('%s目录压缩成功!' % zip_dir)zip.close()# 最后删除创建的目录os.removedirs(zip_dir)

六、目录一对多压缩

以上传邮件附件为例,如果附件太大,将会导致上传失败,那么可以将一个文件压缩成多个小文件。在每次写入压缩文件后,通过调用"os.path.getsize()"方法检查当前压缩文件的大小,同时引入编号,方便对压缩文件进行命名,在每次检查到压缩文件超过规定大小后,关闭当前写入的压缩文件,压缩文件编号加1并重新拼接新的压缩文件名称,然后创建并写入新的压缩文件。该方法将一个文件压缩成多个压缩文件,实则是新建了多个不同的压缩文件,然后进行写入。代码实现如下:

import os
import zipfilemonth_rank_dir = "img"         # 文件目录
std_file_size = 20000000       # 单个压缩文件的大小i = 1
zip_file_new = month_rank_dir + str(i) + '.zip'
if os.path.exists(month_rank_dir):print('正在为您压缩...')# 打开压缩文件zip = zipfile.ZipFile(zip_file_new, 'w', zipfile.ZIP_DEFLATED)for dir_path, dir_names, file_names in os.walk(month_rank_dir):# 去掉目标跟路径,只对目标文件夹下面的文件及文件夹进行压缩fpath = dir_path.replace(month_rank_dir, '')for filename in file_names:zip.write(os.path.join(dir_path, filename), os.path.join(fpath, filename))# 判断压缩文件是否超标if os.path.getsize(zip_file_new) > std_file_size:print('当前压缩文件的大小为:%s, 正在为您创建新的压缩文件...' % os.path.getsize(zip_file_new))zip.close()i = i+1zip_file_new = month_rank_dir + str(i) + '.zip'zip = zipfile.ZipFile(zip_file_new, 'w', zipfile.ZIP_DEFLATED)zip.close()print('该目录压缩成功!')
else:print('您要压缩的目录不存在...')

上图实现了对当前目录中的img文件夹进行压缩,该文件夹包含了pixiv网站的插画原图,经过压缩后生成img1~6.zip六个文件,如下图。

python zip压缩文件相关推荐

  1. Python将Pandas中Dataframe数据保存为gzip/zip文件:gzip压缩文件、zip压缩文件

    Python将Pandas中Dataframe数据保存为gzip/zip文件:gzip压缩文件.zip压缩文件 目录 Python将Pandas中Dataframe数据保存为gzip/zip文件:gz ...

  2. ksd文件怎么导入存档_DAY5-step5 Python 示例说明 ZIP 压缩文件

    Python使您可以快速创建zip或者tar压缩文档. 以下命令将压缩整个目录 shutil.make_archive(output_filename, 'zip', dir_name) 以下命令使您 ...

  3. 暴力破解(一)——python脚本暴力破解 加密的zip压缩文件

    简介: zip格式是常见的压缩文件格式,它支持压缩时设置解压密码:有两种加密方式:1传统加密方式和普通的加密方式.传统加密方式是一种比较简单的加密方式,现在一般很少有人使用,而且压缩时 系统默认选择的 ...

  4. Python读写zip压缩文件

    摘要: Python自带模块zipfile可以完成zip压缩文件的读写,而且使用非常方便,下面我们就来演示一下Python读写zip文件. Python读zip文件 下面的代码给出了用Python读取 ...

  5. Python读写zip压缩文件的方法

    Python 内置的 zipfile 模块可以对文件(夹)进行ZIP格式的压缩和读取操作.要进行相关操作,首先需要实例化一个 ZipFile 对象.ZipFile 接受一个字符串格式压缩包名称作为它的 ...

  6. python压缩文件操作_Python tar、zip压缩文件操作方法

    python语言源码练习,tar.zip压缩文件操作方法参考示例. import os import threading, zipfile import tarfile class AsyncZip( ...

  7. [Python] 读取 rar/zip 压缩文件

    一. 读取 rar 文件 Python 中 python-unrar 模块依赖于 UnRAR library, 所以需要先安装 UnRAR library 1. 安装 UnRAR library 在官 ...

  8. Python的压缩文件处理 zipfile tarfile

    本文从以下两个方面, 阐述Python的压缩文件处理方式: 一. zipfile 二. tarfile 一. zipfile 虽然叫zipfile,但是除了zip之外,rar,war,jar这些压缩( ...

  9. python gzip压缩文件

    python gzip压缩文件 下面的代码实现用gzip格式压缩文件,需要引用gzip包. #! import string import gzip from optparse import Opti ...

  10. zip压缩文件暴力破解

    对于一个zip格式的压缩包,默认密码是6位数字.暴力破解的基本思路是,调用Python中的zipfile模块的trypassword函数,尝试从0到999999的所有数字,成功解压时即为相应的压缩密码 ...

最新文章

  1. Android Studio安装配置、环境搭建详细步骤及基本使用
  2. python写的游戏怎么给别人玩-用python写游戏脚本原来这么简单
  3. 使用AOP+Annotation实现操作日志记录
  4. ssh 与 locale
  5. 视图中::text_新CalendarFX视图:MonthGridView!
  6. 往vxe-table添加渲染器怎么添_赚大了!飘窗上装书桌,加扇折叠窗,等于为家里又多添一间房...
  7. 怎么把matlab仿真数据压缩,JPEG图像压缩编码及其MATLAB仿真实现(1)
  8. [sublime] sublime 实现Markdown编辑器
  9. Vue.js如何搭建本地dev server
  10. Android Performance之开机优化(1)-开机启动优化工具
  11. List集合排序(Lambda表达式)
  12. 期货反向跟单这个模式、大家目前都耳熟能详,操作原理也算是人尽皆知了!
  13. 怎么在MATLAB中看奈氏图的S平面,MATLAB频域分析,奈氏图、伯德图、对数幅相图绘制...
  14. 网络何时能ping通?什么情况下不能ping通?
  15. 批判性思维过程之 理性、感性的抉择
  16. 【花雕体验】19 合宙ESP32_C3点亮WS2812B硬屏
  17. Mysql开启3306端口远程访问
  18. minisforum HX90G/HX99G miniPC-Hackintosh-Opencore 黑苹果efi引导文件
  19. 立志入行网络或已经初入行的朋友的建议
  20. C语言中printf格式详解

热门文章

  1. 江南大学计算机考研资料汇总
  2. 为什么我们会有假期一结束,快乐就终止的感觉?
  3. mapgis矢量化怎么打分数_MAPGIS矢量化步骤
  4. python sample函数取样,python sample函数取样_Pytorch各种取样器sample
  5. 卖肉了也没火的十大悲催女星
  6. “35岁,我退休了”:关于中年危机,这是最靠谱的回答
  7. 埃默里大学又一华人科学家被要求搬离实验室,当事人称“这是报复”
  8. 为什么要使用PPTP协议代理ip?
  9. html边界填充边框,CSS边界与填充
  10. CCS编译错误:error #10099-D和error#10234-D unresolved symbols remain解决方法