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

分类:python    110人阅读    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'./中文不乱码')

 

服务器费用不足...

Hotspot Map - 强大的图片热点注释和提示工具

UFO适合404页面的jQuery特效

CSS3机械工业风齿轮转动特效

JS+CSS3卡通汽车行驶特效

滚动下拉图片切斜HTML5特效

物品租赁买卖业务平台HTML5模板 - Doremi

程序员向妹子表白专用代码

区块链数字货币管理系统网页模板 - Cryptio

时尚的社交网站前端界面HTML模板 - Cirkle

bootstrap框架web UI工具包后台模板 - MegaDin

JavaScript模拟网页星际旅行特效

一个alert网页小部件

建筑工程机械设备租赁网站HTML模板 - Antek

黑客帝国文字雨矩阵动画特效

给乌龟喂食卡通HTML5特效

HTML5大气导航栏鼠标悬停特效

Vue 3、Vite和TailwindCss开发的管理面板

Vue轻量级后台管理系统基础框架模板--精

时尚和轻量设计Bootstrap4管理系统模板 - Sunny

bootstrap风格后台界面管理系统模板 - Voler

服务器费用不足...
 工具推荐 更多»