кодировка zip-файла в python для arcname - PullRequest
2 голосов
/ 15 марта 2012

Я пытаюсь добавить несколько файлов в zip-архив с помощью библиотеки Python zipfile. Проблема заключается в том, что в заархивированном имени файла содержатся специальные символы (utf-8).

Вот базовый код:

#!/usr/bin/env python

import zipfile

infilename = "test_file"
outfilename = "test.zip"
filename = u'Conf\xe9d\xe9ration.txt'

if __name__ == '__main__':
    f = open(outfilename, "w")
    archive = zipfile.ZipFile(f, "w", zipfile.ZIP_DEFLATED)
    archive.write(infilename, filename.encode("CP437"))
    archive.close()
    f.close()

Сгенерированный файл не читается правильно с каждым zip-экстрактором:

  • Ubuntu 10.04 и 11.10: Conf? D? Ration.txt
    Не удалось извлечь файл: «Внимание: имя файла не совпадает: Conf \? D \? Ration.txt»

  • Windows XP & 7: Confédération.txt
    Файл может быть прочитан

  • MacOSX (Лев): ConfÇdÇration.txt
    Файл может быть прочитан

Я пытался без кодирования в CP437 изменить одну строку на:

    archive.write(infilename, filename)

На этот раз в Ubuntu осталась та же проблема, Windows выдает «Conf + ®d + ®ration.txt», а MacOSX работает отлично.

Кто-то знает (питоническое) решение для кросс-платформ?

Спасибо!

1 Ответ

1 голос
/ 10 декабря 2012

Похоже, что имя файла пишется «как есть» (то есть в первый раз оно записывается в кодировке CP437, а во второй - в UTF8), тогда как другие обработчики архивов используют другой подход:

  • Windows: для имен файлов внутри архива используется кодировка DOS / OEM, поэтому CP437 работает. И это поведение описано в стандарте PKWare;
  • Mac OS: он молча использует utf-8, что нарушает стандарт. И вот почему utf8 работает в Mac OS.
  • Linux / Unix: они используют системную кодовую страницу для имен файлов внутри архива, не знают, на какую из них установлена ​​ваша установка Linux, но не для DOS и не для кодировки UTF8:)
...