Les spécifications récentes permettent aux fichiers zip de stocker les noms de fichiers en UTF-8, mais dans de nombreux cas, le code de caractère hérité dépendant de l'environnement est utilisé pour stocker les noms de fichiers. Dans le cas du japonais, Shift-JIS (cp932) est souvent utilisé selon Windows.
Dans Python 2, le nom de fichier renvoyé par le module zipfile était une chaîne d'octets, donc le nom de fichier de cp932 était retourné tel quel, mais dans Python 3, la chaîne de caractères était unifiée en Unicode, donc lorsque le fichier zip est lu, le nom de fichier est décodé. Il sera renvoyé sous forme de chaîne de caractères. Cependant, bien sûr, les coutumes japonaises ne sont pas le comportement par défaut, de sorte que les caractères seront brouillés tels quels.
Quand j'ai lu le module zipfile Python 3.4, il ressemblait à ceci:
if flags & 0x800:
# UTF-8 file names extension
filename = filename.decode('utf-8')
else:
# Historical ZIP filename encoding
filename = filename.decode('cp437')
Une erreur UnicodeDecodeError ne se produirait-elle pas lors du décodage d'une chaîne codée cp932?
>>> len(bytes(range(256)).decode('cp437'))
256
cp437 semble décoder tous les octets un à un par caractère. Donc, il semble bon de ré-encoder avec cp437, puis de décoder à nouveau avec cp932.
import zipfile
zf = zipfile.ZipFile('foo.zip')
for name in zf.namelist():
print(name.encode('cp437').decode('cp932')
Recommended Posts