Python 2与3中处理CJK编码ZIP文件的兼容方案
本文详解在Python 2和Python 3环境下处理包含CJK(中日韩)编码文件名的ZIP压缩包的方法。重点解析Python 3中UTF-8与CP437编码标志位(EFS)的处理逻辑,以及针对非标准编码(如GB18030)的文件名解码策略。通过结合所有文件名进行编码猜测以提高准确性,并提供兼容双版本的代码参考mczip。
近期项目中遇到了包含中文编码的ZIP文件,处理过程耗时较长,特此记录以避后续重复踩坑。
Python 2环境下的处理方案
Python 2环境下的处理方式
在Python 2中读取ZIP文件时,zipfile.ZipInfo对象的filename属性类型为str,其语义类似于Python 3中的bytes,即该字符串可通过decode方法转换为unicode。
因此,处理中文文件名的关键在于将文件名按照指定的编码格式decode为unicode。
import zipfile
fpath = '/path/to/zip.zip'
zfile = zipfile.ZipFile(fpath, 'r')
for fileinfo in zfile.filelist:
print fileinfo.filename.decode('gb18030')
# 如果要更加详细的区分bytes/str/unicode的语义
print bytes(fileinfo.filename).decode('gb18030')
Python 3环境下的编码逻辑与兼容策略
Python 3环境下的处理方式
在Python 3中,若ZIP文件头中的语言编码标志(EFS)为1,则文件名按UTF-8编码处理;若EFS为0,则直接按CP437编码解码文件名,这是ZIP标准的直接规定。
然而,许多软件在创建ZIP压缩包时,并未遵循标准,而是直接使用GB18030或其他非标准编码格式来编码文件名。因此,我们需要先将文件名转换为bytes,再使用对应的编码方式进行解码。
fpath = '/path/to/zip.zip'
zfile = zipfile.ZipFile(fpath, 'r')
for fileinfo in zfile.filelist:
print(fileinfo.filename.encode('cp437').decode('gb18030'))
既然方法已明确,理论上可以根据文件名智能猜测编码后直接解压。但由于单个文件名较短,chardet库的编码猜测可能不准确,因此建议将所有文件名连接成一个长字符串后再进行编码猜测,以提高准确率。
完整代码请参考mczip项目,该方案兼容Python 2和Python 3。
总结
以上介绍了在Python 2和Python 3中处理CJK编码ZIP文件的方法,希望能为遇到类似问题的开发者提供帮助。如有疑问欢迎留言,小编会及时回复。感谢对本站的支持!若本文对您有帮助,欢迎转载,请注明出处,谢谢!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









