在工作中经常会遇见解压邮件或者发过来的压缩文件,最近发现,在zipfile处理中文时,会出现乱码的情况,代码如下:
if ".zip" in os.path.splitext(file)[1]:
path = src_dir + "\\" + file
zip = zipfile.ZipFile(file, 'r') # 待解压文件
zip_list = zip.namelist()
for zip_file in zip_list:
print(zip_file)
print(zip_file.encode('utf-8'))
zip.extractall(src_dir) # 解压指定文件路径
os.remove(path)
zip.close
在zip标准中,对文件名的 encoding 用的不是 unicode,而可能是各种软件根据系统的默认字符集来采用(此为猜测),而zipfile中根据文件 flag 检测的时候,只支持 cp437 和 utf-8。
查明原因后,如果标题已被正确识别为utf8编码时则不需再编码,如未被识别时则出现乱码。经修改如下,即可正常解压。
方法一:
修改zipfile.py文件中两处,重新执行脚本,即可编译成功,不会出现乱码情况
方法二:
网上有很多,解压后将乱码名字修改为正确的中文名字,而实际业务发生时,解压后程序是占用文件,无法修改rename
with zipfile.ZipFile('love.zip', 'r') as zipobj: #读取压缩包
for file_name in zipobj.namelist(): #遍历名称
info = zipobj.getinfo(file_name)
file_name = file_name.encode('cp437').decode('gbk')
lis.append([file_name,info.file_size])
zip_list = zip.namelist()
for zip_file in zip_list:
file_size = zip.getinfo(zip_file).file_size
new_name = zip_file.encode('cp437').decode('gbk')
new_path = os.path.join(src_dir, new_name)
if file_size > 0:
with open(file=new_path, mode='wb') as f:
# zf.read 是读取压缩包里的文件内容
f.write(zip.read(zip_file))
f.close()
zip.close()
# ZipFile.getinfo(name) 方法返回的是一个ZipInfo对象,表示zip文档中相应文件的信息。它支持如下属性:
# ZipInfo.filename: 获取文件名称。
# ZipInfo.date_time: 获取文件最后修改时间。返回一个包含6个元素的元组:(年, 月, 日, 时, 分, 秒)
# ZipInfo.compress_type: 压缩类型。
# ZipInfo.comment: 文档说明。
# ZipInfo.extr: 扩展项数据。
# ZipInfo.create_system: 获取创建该zip文档的系统。
# ZipInfo.create_version: 获取 创建zip文档的PKZIP版本。
# ZipInfo.extract_version: 获取 解压zip文档所需的PKZIP版本。
# ZipInfo.reserved: 预留字段,当前实现总是返回0。
# ZipInfo.flag_bits: zip标志位。
# ZipInfo.volume: 文件头的卷标。
# ZipInfo.internal_attr: 内部属性。
# ZipInfo.external_attr: 外部属性。
# ZipInfo.header_offset: 文件头偏移位。
# ZipInfo.CRC: 未压缩文件的CRC-32。
# ZipInfo.compress_size: 获取压缩后的大小。
# ZipInfo.file_size: 获取未压缩的文件大小。
备注:
若删除过程中提示“解决报错:PermissionError: [WinError 32] 另一个程序正在使用此文件,进程无法访问。PermissionError: [WinError 5] 拒绝访问。” ,则需要关闭所有占用的语句 close ,close()与close 效果不一样,请慎用哈