转载 

Python中ZipFile解压文件名中文乱码的问题

分类:python    708人阅读    IT小君  2022-10-05 20:18

原因分析

zipfile.py中ZipFile在初始化时执行了_RealGetContents方法,目的是读取目录结构,其中关于文件名编码的处理是这样的:

 

# 第42行
if flags & 0x800:
    # UTF-8 file names extension
    filename = filename.decode('utf-8')
else:
    # Historical ZIP filename encoding
    filename = filename.decode('cp437')

要么是utf-8要么是cp437,然而咱们在windows平台上压缩包文件名编码大多是gbk,这里用cp437解码了,所以会乱码

解决办法

只需要将filename重新编码cp437解码成gbk就好了,网络上大多数做法是对解压后的文件和目录操作,不太优雅。优雅一点点的方式是直接修改ZipFile对象中的filename

首先找到filename存在于哪里,同样在_RealGetContents这个函数中找到如下代码

# 第49行
x = ZipInfo(filename)
... # 省略若干行
# self是ZipFile对象
# 第67行
self.filelist.append(x)
self.NameToInfo[x.filename] = x

所以至少有两处存在filename

  • 列表filelist存储的ZipInfo对象的filename属性
  • 字典NameToInfo的键

加个补丁函数把这两处改了试试,代码如下:

from zipfile import ZipFile


def support_gbk(zip_file: ZipFile):
    name_to_info = zip_file.NameToInfo
    # copy map first
    for name, info in name_to_info.copy().items():
        real_name = name.encode('cp437').decode('gbk')
        if real_name != name:
            info.filename = real_name
            del name_to_info[name]
            name_to_info[real_name] = info
    return zip_file


with support_gbk(ZipFile(r'./里面有中文.zip')) as zfp:
    zfp.extractall(r'./中文不乱码')

 

支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者

 工具推荐 更多»