菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
220
0

zipfile

原创
05/13 14:22
阅读数 97594

使用

zipfile.is_zipfile('xxx.zip') # 判断文件是否是个有效的zipfile
zipfile.namelist('xxx.zip') # 列表,存储zip文件中所有子文件的path(相对于zip文件包而言的)
zipfile.infolist('xxx.zip') # 列表,存储每个zip文件中子文件的ZipInfo对象
zipfile.printdir() # 打印输出zip文件的目录结构,包括每个文件的path,修改时间和大小
zipfile.open(name[,mode[,pwd]]) # 获取一个子文件的文件对象,可以对其进行read,readline,write等操作
zipfile.setpassword(psw),为zip文件设置默认密码
zipfile.testzip() # 读取zip中的所有文件,验证他们的CRC校验和。返回第一个损坏文件的名称,如果所有文件都是完整的就返回None
zipfile.write(filename[,arcname[,compression_type]]) # 将zip外的文件filename写入到名为arcname的子文件中(当然arcname也是带有相对zip包的路径的),打开方式为w或a
zipfile.extract(member, path=None, pwd=None) # 解压一个zip中的文件,path为解压存储路径,pwd为密码
zipfile.extractall(path[,pwd]) # 解压zip中的所有文件,path为解压存储路径,pwd为密码

中文乱码问题

内置的zipfile模板在解压zip文件的时候,如果其中文件名称存在中文,将会乱码

原因:
在源码中显示zipfile将所有文件名用cp437进行了编码,官方说明

There is no official file name encoding for ZIP files. If you have unicode file names, you must convert them to byte strings in your desired encoding before passing them to write(). WinZip interprets all file names as encoded in CP437, also known as DOS Latin.

解决方案:
先用 CP437 编码 encode 成 bytes,再以 gbk或者utf-8 格式解码成中文 string。

在解压时不用extractall,要用extract对单个文件进行解压

1 对文件流重新写入

import shutil
import zipfile

with zipfile.ZipFile('文件.zip', 'r') as zf:
    for fn in zf.namelist():
        right_fn = fn.encode('cp437').decode('gbk')  # 将文件名正确编码
        with open(right_fn, 'wb') as output_file:  # 创建并打开新文件
            with zf.open(fn, 'r') as origin_file:  # 打开原文件
                shutil.copyfileobj(origin_file, output_file)  # 将原文件内容复制到新文件

2 解压后对文件进行重命名

        with zipfile.ZipFile(zipfile_path, 'r') as zip_file:
            for file_name in zip_file.namelist():
                file_path = Path(zip_file.extract(file_name, dest_path))
                print(file_path)
                try:
                    file_name = file_name.encode('cp437').decode('gbk')
                except:
                    file_name = file_name.encode('cp437').decode('utf-8')
                file_path.rename(os.path.join(dest_path, file_name))

3 使用os调用终端命令unzip进行解压

-O cp936解除中文乱码,部分机器需要, -o直接覆盖,不展示交互命令
os.popen(f'cd {dest_path} && unzip -O cp936 -o {}')

感谢 https://blog.csdn.net/u010099080/article/details/79829247

发表评论

0/200
220 点赞
0 评论
收藏