解压缩zip文件
import zipfile import os.path import os class ZFile(object): """ 文件压缩 """ def zip_file(self, fs_name, fz_name): """ 从压缩文件 :param fs_name: 源文件名 :param fz_name: 压缩后文件名 :return: """ flag = False if fs_name and fz_name: try: with zipfile.ZipFile(fz_name, mode='w', compression=zipfile.ZIP_DEFLATED) as zipf: zipf.write(fs_name) print( "%s is running [%s] " % (currentThread().getName(), fs_name)) print('压缩文件[{}]成功'.format(fs_name)) if zipfile.is_zipfile(fz_name): os.remove(fs_name) print('删除文件[{}]成功'.format(fs_name)) flag = True except Exception as e: print('压缩文件[{}]失败'.format(fs_name), str(e)) else: print('文件名不能为空') return {'file_name': fs_name, 'flag': flag} def unzip_file(self, fz_name, path): """ 解压缩文件 :param fz_name: zip文件 :param path: 解压缩路径 :return: """ flag = False if zipfile.is_zipfile(fz_name): # 检查是否为zip文件 with zipfile.ZipFile(fz_name, 'r') as zipf: zipf.extractall(path) # for p in zipf.namelist(): # # 使用cp437对文件名进行解码还原, win下一般使用的是gbk编码 # p = p.encode('cp437').decode('gbk') # 解决中文乱码 # print(fz_name, p,path) flag = True return {'file_name': fz_name, 'flag': flag}
解决中文乱码问题:
在zip标准中,对文件名的 encoding 用的不是 unicode,而可能是各种软件根据系统的默认字符集来采用(此为猜测),因此zipfile中根据文件 flag 检测的时候,只支持 cp437 和 utf-8。具体就是查找 zipfile.py 源代码找到下面的代码:
找到python3 的安装目录, 搜索 zipfile.py这个文件,改两个地方
可见编码被正确识别为utf8时的情况外,都会被识别并decode为cp437编码,但如果实际是gbk等其他编码时就变为乱码了
第一.
if zinfo.flag_bits & 0x800: # UTF-8 filename fname_str = fname.decode("utf-8") else: # fname_str = fname.decode("cp437") fname_str = fname.decode("gbk") # 这句是我添加的 解决win下中文乱码
第二..
if flags & 0x800: # UTF-8 file names extension filename = filename.decode('utf-8') else: # Historical ZIP filename encoding # filename = filename.decode('cp437') filename = filename.decode("gbk") # 这句是我添加的,解决win下中文乱码问题