前言
最近在接受他人上传的 ZIP 压缩包时,发现解压后文件名出现了乱码,记得自己很久以前似乎把系统的编码改为了 UTF,所以盲猜是压缩包发送人的系统使用了 GBK 编码,出现了错误。
正文
探索
搜了一下,发现了知乎上一个很好的回答如下,基本就是说其实文件信息没有出问题,但是文件名编码方式通常会使用压缩方的编码。回答中给出了一种解法是使用 Bandzip 和 360 压缩 ,我是万年 7z 用户,但是却发现 7z 没有做相关的设置选项。暂时不考虑使用 Bandzip。
首先要先保证文件是确实可以解码出正确结果的,搜了一下 Linux 环境下可以使用 unzip -O GBK来指定编码。
试了一下把压缩包拖到 Linux 系统,用下面的命令解压确实可以。
unzip -O GBK xxx.zip
所以其实到这里第一种 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)
下载和安装都很快,自动绑定了一下后缀名,然后打开压缩包,可以看到默认还是乱码。
但是按照提示点自动检测,如下图。
问题解决。