OS X benutzt übrigens, wenn es ein ZIP-Archiv mit einer Datei mit Umlauten erzeugt, dort das eigene interne Encoding, also UTF-8 mit canonical decomposition ab. Um das aber in das üblichere Format zu verwandeln, müsste man dies machen:
Code: Alles auswählen
unicodedata.normalize("NFC", zip_info.filename.decode("utf-8"))
Nutze ich das Kommandozeilen-Programm "zip" (Info-ZIP 3.0) landet darin der Dateiname UTF-8-kodiert, aber pre-combined, so wie es üblicher ist.
Der Standard sagt:
The ZIP format has historically supported only the original IBM PC character
encoding set, commonly referred to as IBM Code Page 437. This limits storing
file name characters to only those within the original MS-DOS range of values
and does not properly support file names in other character encodings, or
languages. To address this limitation, this specification will support the
following change.
If general purpose bit 11 is unset, the file name and comment should conform
to the original ZIP character encoding. If general purpose bit 11 is set, the
filename and comment must support The Unicode Standard, Version 4.1.0 or
greater using the character encoding form defined by the UTF-8 storage
specification.
Wurde dieses Bit gesetzt?
Code: Alles auswählen
0000000 50 4b 03 04 0a 00 00 00 00 00 f2 4c 11 3f 00 00
0000020 00 00 00 00 00 00 00 00 00 00 0c 00 1c 00 c3 a4
0000040 c3 b6 c3 bc c3 9f 2e 74 78 74 55 54 09 00 03 38
0000060 70 4b 4e 38 70 4b 4e 75 78 0b 00 01 04 f5 01 00
0000100 00 04 00 00 00 00 50 4b 01 02 1e 03 0a 00 00 00
0000120 00 00 f2 4c 11 3f 00 00 00 00 00 00 00 00 00 00
0000140 00 00 0c 00 18 00 00 00 00 00 00 00 00 00 a4 81
0000160 00 00 00 00 c3 a4 c3 b6 c3 bc c3 9f 2e 74 78 74
0000200 55 54 05 00 03 38 70 4b 4e 75 78 0b 00 01 04 f5
0000220 01 00 00 04 00 00 00 00 50 4b 05 06 00 00 00 00
0000240 01 00 01 00 52 00 00 00 46 00 00 00 00 00
0000256
AFAICT nein. Wie schade. Die ersten 4 Bytes signalisieren einen locale file header. Danach kommen 2 Bytes Version (10); danach die Flags (0). Da müsste 04 00 stehen, würde ich sagen.
Info-ZIP scheint sich damit über den Standard hinwegzusetzen. Dessen Hilfe sagt:
Code: Alles auswählen
Unicode:
If compiled with Unicode support, Zip stores UTF-8 path of entries.
This is backward compatible. Unicode paths allow better conversion
of entry names between different character sets.
Man könnte wohl das 0x0008-Extra Field hinzufügen, und darin signalisieren, welches Encoding ein Name (und der Kommentar) haben, doch das ist bei mir ja nicht der Fall.
Was sagt uns das alles: Wenn man selbst eine ZIP-Datei erzeugt, sollte man Bit 11 setzen und den Namen UTF-8-kodieren.
Code: Alles auswählen
z = zipfile.ZipFile("test.zip", "w")
zi = zipfile.ZipInfo(u"äöü".encode("utf-8"))
zi.flag_bits = 1024
z.writestr(zi, "...")
z.close()
Stefan