1 压缩 1.1 创建zipfile对象 zipfile.ZipFile(file, mode='r', compression=0, allowZip64=True, compresslevel=None) 创建Zipfile对象,主要参数: 1>file压缩包名称; 2>mode:读’r’或者写’w’模式; 3>compression:设置压缩格式; 4>compresslevel:压缩等级; 压缩格式分类: 格式 说明 对应compresslevel ZIP_STORED 不压缩 无效 ZIP_DEFLATED 需要zlib支持 0~9 ZIP_BZIP2 需要bz2支持 0~9 ZIP_LZMA 需要lzma支持 无效 1.2 添加压缩文件 zipobj.write(self, filename, arcname=None, compress_type=None, compresslevel=None) 参数说明: 1>fiename:添加文件路径; 2>arcname:归档文件路径与名称; 1.3 添加压缩数据 zipobj.writestr(zinfo_or_arcname, data, compress_type=None, compresslevel=None) 参数说明: 1>zinfo_or_arcname:归档文件名称; 2>data:压缩数据str或者byte,如果数据为str,需要先进行Utf-8编码; 1.4 关闭 关闭压缩文件: zipobj.close() 1.5 一个例子: 压缩目录如下:代码实现: import zipfile logdir = '/home/linux/logs' zipname = '/home/linux/logs.zip' #创建zip对象, fzip = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED) #遍历要压缩目录 flist = os.listdir(logdir) for name in flist: fpath = os.path.join(logdir, name) #写入要压缩文件 fzip.write(fpath) #关闭 fzip.close() 进入目录解压,文件路径如下:
可以看到,我们将整个目录添加到压缩文件中,其实我们更想做的是logs/*.log; 对代码进行修改: logdir = '/home/linux/logs' zipname = '/home/linux/logs.zip' import zipfile #创建zip对象, fzip = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED) #遍历要压缩目录 flist = os.listdir(logdir) #获取压缩目录名称 basename = os.path.basename(logdir) for name in flist: fpath = os.path.join(logdir, name) arcname = os.path.join(basename, name) #写入要压缩文件,并添加归档文件名称 fzip.write(fpath, arcname=arcname) #关闭 fzip.close() 压缩之后,解压缩内容:
这个才是我们想要的。 2.获取压缩包信息 打开压缩包: frzip = zipfile.ZipFile(zipname, ‘r’, zipfile.ZIP_DEFLATED):只读方式打开; frzip.printdir(),显示压缩包文件信息 File Name Modified Size logs/1003.log 2019-04-09 10:00:10 17 logs/1001.log 2019-04-09 10:00:06 17 logs/1004.log 2019-04-09 10:00:12 17 logs/1002.log 2019-04-09 10:00:08 17 logs/1000.log 2019-04-09 10:00:04 17 frzip.filelist:记录压缩包文件信息,与printdir类似,内容如下: [<ZipInfo filename='logs/1003.log' compress_type=deflate filemode='-rw-r--r--' file_size=17 compress_size=17>, <ZipInfo filename='logs/1001.log' compress_type=deflate filemode='-rw-r--r--' file_size=17 compress_size=17>, <ZipInfo filename='logs/1004.log' compress_type=deflate filemode='-rw-r--r--' file_size=17 compress_size=17>, <ZipInfo filename='logs/1002.log' compress_type=deflate filemode='-rw-r--r--' file_size=17 compress_size=17>, <ZipInfo filename='logs/1000.log' compress_type=deflate filemode='-rw-r--r--' file_size=17 compress_size=17>] frzip.getinfo(name):获取指定arcname的信息: frzip.getinfo('logs/1003.log') #输出结果: <ZipInfo filename='logs/1003.log' compress_type=deflate filemode='-rw-r--r--' file_size=17 compress_size=17> frzip.namelist():获取压缩文件列表 ['logs/1003.log', 'logs/1001.log', 'logs/1004.log', 'logs/1002.log', 'logs/1000.log'] 3 解压压缩包 frzip.extract(member, path=None, pwd=None):解压缩一个文件到指定目录; 参数: member:压缩包中文件; path:解压缩到指定目录,默认解压到当前目录; frzip.extractall(path=None, members=None, pwd=None):解压缩多个文件到指定目录; 参数: path:指定的解压目录; members:指定解压文件,默认解压全部; 解压指定文件到指定目录: #可以自己定义路径 zipname = '/home/linux/logs.zip' extractpath = '/home/linux/1' #注意压缩格式选择 frzip = zipfile.ZipFile(zipname, 'r', zipfile.ZIP_DEFLATED) extractfile = frzip.namelist() if len(extractfile): extname = extractfile[0] print('extract file:', extname) frzip.extract(extractfile[0], extractpath) frzip.close() 输出结果:extract file: logs/1003.log,在extractpath目录下有log文件; 使用frzip.extractall将所有文件解压到指定目录: #可以自己定义路径 zipname = '/home/linux/logs.zip' extractpath = '/home/linux/1' #注意压缩格式选择 frzip = zipfile.ZipFile(zipname, 'r', zipfile.ZIP_DEFLATED) #将所有文件加压缩到指定目录 frzip.extractall(extractpath) frzip.close() 除了zipfile还有其它模块: import gzip; import tarfile; 这些模块使用方式都类似。
有时候我们经常用到.zip压缩包文件,而Python内置了zipfile模块可以处理zip压缩文件。
读取压缩包内的文件名称
zipfile.ZipFile() / .namelist() 注意大小写问题
1
2
3
4
5
|
# 引入zipfile模块 import zipfile with zipfile.ZipFile( 'demo.zip' , 'r' ) as zzz: print (zzz.namelist()) # 运行结果:['file1.txt', 'file2.txt', 'temp_file.png'] |
如果压缩包里的文件名有中文,则容易出现乱码,所以这时候,需要对中文文件名进行转码:
1
2
3
4
5
6
7
8
|
with zipfile.ZipFile( 'demo.zip' , 'r' ) as zzz: for f_name in zzz.namelist(): print (f_name.encode( 'cp437' ).decode( 'gbk' )) ''' 运行结果: file1.txt file2.txt temp_file.png 数据分析.PNG''' |
读取压缩包内文件信息
.getinfo() 读取文件信息
1
2
3
4
5
6
7
8
9
10
11
12
|
with zipfile.ZipFile( 'demo.zip' , 'r' ) as zzz: for f_name in zzz.namelist(): f_info = zzz.getinfo(f_name) f_name = f_name.encode( 'cp437' ).decode( 'gbk' ) # 输出该文件的文件大小.file_size和压缩之后的大小compress_size print (f_name,f_info.file_size,f_info.compress_size) ''' 运行结果: file1.txt 98 47 file2.txt 98 47 temp_file.png 22061 18211 数据分析.PNG 178210 177931''' # 除了大小之外.getinfo()还可以读取出filename、compress_type、external_attr属性。 |
从压缩包里解压文件
.extract() 可以把某个文件从.zip压缩包里解压出来
格式:.extract('要解压的zip文件名','解压到的位置') 如果不填写解压的位置,则默认解压到当前目录
1
2
3
4
|
with zipfile.ZipFile( 'demo.zip' , 'r' ) as zzz: zzz.extract( 'file1.txt' ) # 把压缩包里的file1.txt解压到当前目录 # 如果压缩包里出现中文,则需要进行转码(所以在用Python压缩文件和解压的时候最好不要出现中文路径和文件名) |
如果被解压的文件名里有中文,则可以先解压,然后再重命名。
1
2
3
4
5
6
7
8
9
10
|
import zipfile,os # 需要用到os模块 with zipfile.ZipFile( 'demo.zip' , 'r' ) as z: f_name = '添加数据.png' # 把压缩包里的 添加数据.png 文件解压出来 f_temp = f_name.encode( 'gbk' ).decode( 'cp437' ) z.extract(f_temp, 'D:\\Temp\\' ) # 解压到 D:\Temp\ os.rename(f 'D:\\Temp\\{f_temp}' ,f 'D:\\Temp\\{f_name}' ) # 重新命名为中文 |
.extractall() 可以把压缩包里的所有文件解压到指定目录
格式:.extractall('解压到的位置') 如果不写则解压到当前目录
1
2
3
|
with zipfile.ZipFile( 'demo.zip' , 'r' ) as zzz: zzz.extractall( '文件夹1' ) # 把所有文件解压到 文件夹1 下面 |
解压带密码的压缩包
格式:.extractall('解压到的位置',pwd=b'密码')
1
2
|
with zipfile.ZipFile( 'Python.zip' , 'r' ) as zzz: zzz.extractall( '解压到这里' ,pwd = b '123456' ) |
所以这里我们一个破解密码的可能,就是如果有一个密码列表,可以挨个试列表中的字符。或者知道密码的位数,就可以用遍历的方式暴力破解。
创建.zip压缩包
创建zip压缩包文件使用‘w’参数,同时用到.write()函数将指定文件添加到压缩包,使用方式是.write('被压缩的文件名或路径')。
注意,参数为'w'的话,如果存在同名sample.zip文件的话,会被新创建的覆盖掉。
1
2
3
|
with zipfile.ZipFile( 'sample.zip' , 'w' ) as z: # 创建文件夹的话,参数为‘w’ z.write( 'file1.txt' ) |
创建zip压缩包的时候,把多个文件批量添加到压缩包里,可以把文件名(路径)赋值给一个列表,然后用遍历的方式,把文件批量添加到压缩包里。
1
2
3
4
|
f_list = [ 'file1.txt' , 'file2.txt' , 'temp_file.png' , './py/hello.py' ] with zipfile.ZipFile( 'sample.zip' , 'w' ) as z: for f_name in f_list: z.write(f_name) |
向已有的zip压缩包里添加文件
上面提到,如果用'w'参数的话,那么向压缩包里添加文件,则会覆盖之前的压缩包。而向已有的压缩包添加文件,而不是替换这个压缩包的话,需要使用'a'参数,其他方法相同。
1
2
3
4
|
f_list = [ 'temp_folder.png' , './py/game.py' ] with zipfile.ZipFile( 'sample.zip' , 'a' ) as z: for f_name in f_list: z.write(f_name) |
如果压缩包里有同名文件,可以添加成功,但是会报警,提示1515: UserWarning: Duplicate name: 'temp_folder.png'.