转载 

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

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

 

点击广告,支持我们为你提供更好的服务

立体空间感3d几何体破碎

法律服务和律师事务所HTML5模板 - AttorCo

CSS鼠标停靠图标变大

CSS DIV画的字母Q

canvas生日快乐动画特效

百分比加载进度SVG线条动画

功能齐全的ReactJs管理模板 - Adminto

环绕式按钮菜单

技能培训在线学习平台网站模板 - Collab

Tailwindcss高级管理后台模板框架 - T-Wind

原子模型CSS3动画

CSS 3D铅笔旋转效果

创意代理和初创公司HTML模板 - Wan

按钮的hover效果覆盖过渡

残障人士服务网站HTML模板 - Medixare

单页形式个人主页HTML模板 - Wedo

市政府和行政机构HTML5模板 - Towngov

three.js立体感粒子动画

React实现的电子商务管理后台模板 - Dashtar

SEO和数字营销机构HTML模板 - SEOMY

点击广告,支持我们为你提供更好的服务
 工具推荐 更多»
点击广告,支持我们为你提供更好的服务