gpt4 book ai didi

string - ZipFile 中的 namelist() 返回编码无效的字符串

转载 作者:行者123 更新时间:2023-12-04 06:16:24 24 4
gpt4 key购买 nike

问题在于,对于某些上传到 python 应用程序的文件或文件,ZipFilenamelist()返回解码错误的字符串。

from zip import ZipFile
for name in ZipFile('zipfile.zip').namelist():
print('Listing zip files: %s' % name)

如何修复该代码,以便我始终以 unicode 解码文件名(因此支持中文、俄语和其他语言)?

我已经看到了 Python 2 的一些示例,但是由于字符串的性质在 python3 中发生了变化,我不知道如何重新编码它,或者在它上面应用 chardet。

最佳答案

How to fix that code so i always decode file names in unicode (so Chineeze, Russian and other languages supported)?



自动地?你不能。基本 ZIP 文件中的文件名是没有附加编码信息的字节串,因此除非您知道创建 ZIP 的机器上的编码是什么,否则您无法可靠地获得人类可读的文件名。

现代 ZIP 文件上的标志有一个扩展名,告诉您文件名是 UTF-8。不幸的是,您从 Windows 用户那里收到的文件通常没有它,因此您将使用像 chardet 这样的固有不可靠方法进行猜测。

I've seen some samples for Python 2, but since string's nature is changed in python3, i have no clue how to re-encode it, or apply chardet on it.



Python 2 只会给你原始字节。在 Python 3 中,新行为是:
  • 如果设置了 UTF-8 标志,它会使用 UTF-8 解码文件名,然后您会得到正确的字符串值
  • 否则,它会使用 DOS 代码页 437 对文件名进行解码,这不太可能是预期的。但是,您可以将字符串重新编码回原始字节,然后尝试使用您真正想要的代码页再次解码,例如 name.encode('cp437').decode('cp1252') .

  • 不幸的是(再次,因为不幸的事情永远不会在涉及 ZIP 的地方结束), ZipFile无声地进行解码而不告诉您它做了什么。因此,如果您想切换并仅在文件名可疑时执行转码步骤,则必须复制嗅探是否设置了 UTF-8 标志的逻辑:
    ZIP_FILENAME_UTF8_FLAG = 0x800

    for info in ZipFile('zipfile.zip').filelist():
    filename = info.filename
    if info.flag_bits & ZIP_FILENAME_UTF8_FLAG == 0:
    filename_bytes = filename.encode('437')
    guessed_encoding = chardet.detect(filename_bytes)['encoding'] or 'cp1252'
    filename = filename_bytes.decode(guessed_encoding, 'replace')
    ...

    关于string - ZipFile 中的 namelist() 返回编码无效的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37723505/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com