Neuere Spezifikationen ermöglichen es ZIP-Dateien, Dateinamen in UTF-8 zu speichern. In vielen Fällen wird jedoch der ältere umgebungsabhängige Zeichencode zum Speichern der Dateinamen verwendet. Im Falle von Japanisch wird Shift-JIS (cp932) laut Windows häufig verwendet.
In Python 2 war der vom zipfile-Modul zurückgegebene Dateiname eine Bytezeichenfolge, sodass der Dateiname von cp932 unverändert zurückgegeben wurde. In Python 3 wurde die Zeichenfolge jedoch mit Unicode vereinheitlicht. Wenn die Zip-Datei gelesen wird, wird der Dateiname dekodiert. Es wird als Zeichenfolge zurückgegeben. Natürlich sind japanische Bräuche nicht das Standardverhalten, daher werden die Zeichen so wie sie sind verstümmelt.
Als ich das Python 3.4-Zipfile-Modul las, sah es so aus:
if flags & 0x800:
# UTF-8 file names extension
filename = filename.decode('utf-8')
else:
# Historical ZIP filename encoding
filename = filename.decode('cp437')
Würde beim Dekodieren einer cp932-codierten Zeichenfolge kein UnicodeDecodeError auftreten?
>>> len(bytes(range(256)).decode('cp437'))
256
cp437 scheint alle Bytes eins zu eins pro Zeichen zu dekodieren. Es scheint also gut, mit cp437 neu zu codieren und dann erneut mit cp932 zu decodieren.
import zipfile
zf = zipfile.ZipFile('foo.zip')
for name in zf.namelist():
print(name.encode('cp437').decode('cp932')
Recommended Posts