Использование символов Юникода для имен файлов внутри zip-архива - PullRequest
8 голосов
/ 02 апреля 2012

Я архивирую имя файла, содержащее некоторые специальные символы, такие как Перенос LES HOPITAUX NEUFS.xls в другую папку, скажем temp .

Я могуzip файл, но проблема в том, что имя файла меняется автоматически на P + ¬r + ¬quation LES HOPITAUX NEUFS.xls .

Как я могу поддерживать символы юникода для имен файлов внутри zipархив

Ответы [ 2 ]

16 голосов
/ 02 апреля 2012

Это немного зависит от того, какой код вы используете для создания архива. старые классы сжатия Java не так гибки, как вам нужно.

Вы можете использовать Apache Commons Compress . Майкл Симонс написал этот замечательный кусок кода:

ZipArchiveOutputStream ostream = ...; // Your initialization code here
ostream.setEncoding("Cp437"); // This should handle your "special" characters
ostream.setFallbackToUTF8(true); // For "unknown" characters!
ostream.setUseLanguageEncodingFlag(true);                               
ostream.setCreateUnicodeExtraFields(
    ZipArchiveOutputStream.UnicodeExtraFieldPolicy.NOT_ENCODEABLE);

Если вы используете Java 7 , то у вас наконец-то есть параметр Charset (который может бытьUTF-8) в конструкторе ZipOutputStream

В любом случае, большая проблема заключается в том, что многие реализации не понимают кодировку Unicode, поскольку оригинальный формат файла ZIP - ASCII ине существует официального стандарта для Unicode.См. этот пост для получения дополнительной информации.

7 голосов
/ 02 апреля 2012

В спецификации Zip (исторически) не указывается, какую кодировку символов использовать для имен и комментариев встроенных файлов. Предполагается, что исходная кодировка символов IBM PC, обычно называемая IBM Code Page 437, является единственной кодировкой. поддерживается. В то же время спецификация Jar явно указывает на использование UTF-8 в качестве кодировки для кодирования и декодирования всех имен файлов и комментариев в файлах Jar. Наши реализации java.util.jar и java.util.zip строго следовали спецификации Jar, чтобы использовать UTF-8 в качестве единственной кодировки при работе с именами файлов и комментариями, хранящимися в файлах Jar / Zip.

Последствие? ZIP-файл, созданный «традиционным» ZIP-инструментом, недоступен для инструмента на основе java.util.jar / zip, и наоборот, если имя файла содержит символы, несовместимые с Cp437 (в качестве альтернативы, инструменты могут просто использовать кодировка платформы по умолчанию) и UTF-8

В большинстве европейских стран вам «везет» :-), вам нужно всего лишь избегать «горстки» символов, таких как умлауты (хорошо, я просто шучу), но для японцев и китайцев большинство персонажам просто не повезло. Вот почему ошибка 4244499 была на первом месте среди 25 самых популярных ошибок Java в течение многих лет. Бага больше нет в списке :-) он был окончательно "исправлен" в OpenJDK 7, b57. Я до сих пор храню снимок как запись / кудо для себя: -)

Решение (я бы использовал «решение», а не «исправление») в JDK7 b57 состоит в том, чтобы ввести в новый набор конструкторов ZipInputStream ZipOutStream и ZipFile со специфическим «charset» в качестве параметра, как показано ниже.

ZipFile (файл, кодировка)

ZipInputStream (InputStream, Charset)

ZipOutputStream (OutputStream, Charset)

С помощью этих новых конструкторов приложения теперь могут получать доступ к тем ZIP-файлам, отличным от UTF-8, через объекты ZipInputStream или ZipFile, созданные с определенной кодировкой, или создавать файлы Zip, закодированные в не-UTF-8, с помощью нового ZipOutputStream (os, charset) конструктор, если необходимо.

zip - это урезанная версия инструмента Jar с опцией «-encoding» для поддержки кодировки не-UTF8 для имени записи и комментария, она может служить демонстрацией того, как использовать новые API (я использовал его как юнит тест). Я все еще спорю с собой, стоит ли официально вводить «-кодирование» в инструмент Jar…

...