前言

 

最近在接受他人上传的 ZIP 压缩包时,发现解压后文件名出现了乱码,记得自己很久以前似乎把系统的编码改为了 UTF,所以盲猜是压缩包发送人的系统使用了 GBK 编码,出现了错误。

python linux extractall解压文件乱码_运维

正文

探索

搜了一下,发现了知乎上一个很好的回答如下,基本就是说其实文件信息没有出问题,但是文件名编码方式通常会使用压缩方的编码。回答中给出了一种解法是使用 Bandzip 和 360 压缩 ,我是万年 7z 用户,但是却发现 7z 没有做相关的设置选项。暂时不考虑使用 Bandzip。


首先要先保证文件是确实可以解码出正确结果的,搜了一下 Linux 环境下可以使用 unzip -O GBK来指定编码。

试了一下把压缩包拖到 Linux 系统,用下面的命令解压确实可以。

unzip -O GBK xxx.zip

python linux extractall解压文件乱码_windows_02

所以其实到这里第一种 solution 就有了,可以直接用 Linux 的 unzip -O 来解决。(可以使用 WSL 或者容器或者虚拟机或者远程服务器)但是我这边有很多压缩包,要批量处理就要考虑 Linux 上写脚本了,另外有些场景可能不方便搬运到 Linux 环境。

Python 批量转编码(失败)

又不想换压缩软件,又不想用 Linux,想到了一种鲁莽的解法,就是直接 7z 解压不误,然后用 Python 批量处理所有文件名,把文件名字符串从 GBK 编码转 UTF-8 就好。

结果尝试后发现,直接解压后乱码的文件名,已经不再是原来的字节序列了,无法显示的字节序列已经被处理为了特殊符号,所以乱码文件名转字节序列后大致内容如下。可以看到乱码的字符已经被批量替换了,无法恢复出原始的GBK字节序列也就无法得到原来的中文内容。

���п��Էǵݹ�.cpp
b'\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd0\xbf\xef\xbf\xbd\xef\xbf\xbd\xd4\xb7\xc7\xb5\xdd\xb9\xef\xbf\xbd.cpp'
���п��Էǵݹ�.exe
b'\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xd0\xbf\xef\xbf\xbd\xef\xbf\xbd\xd4\xb7\xc7\xb5\xdd\xb9\xef\xbf\xbd.exe'

直接 encode('gbk') 会报错如下:

Traceback (most recent call last):
  File "d:\xxx\filename_GBK2UTF.py", line 41, in <module>
    newfile = file.encode('gbk')
UnicodeEncodeError: 'gbk' codec can't encode character '\ufffd' in position 0: illegal multibyte sequence

Bandizip 真香

下载链接:Windows 版本的 Bandizip · 业内领先的压缩文件解决方案 (bandisoft.com)

下载和安装都很快,自动绑定了一下后缀名,然后打开压缩包,可以看到默认还是乱码。

python linux extractall解压文件乱码_字节序_03

但是按照提示点自动检测,如下图。

python linux extractall解压文件乱码_运维_04

 问题解决。

python linux extractall解压文件乱码_文件名_05