#java #encoding #properties #internationalization
Вопрос:
Я экспериментирую с интернационализацией, создавая программу Hello World, которая использует файлы свойств ResourceBundle для получения разных строк.
В частности, у меня есть файл «messages_en_US.properties», в котором хранится «hello.world=Привет, мир!», который, конечно, отлично работает.
Затем у меня есть файл «messages_ja_JP.properties», с которым я пробовал всевозможные вещи, но он всегда отображается как какая-то искаженная строка при печати на консоли или в Swing. Проблема, очевидно, связана с чтением содержимого в строку Java, так как строка Java на японском языке, введенная непосредственно в исходный код, может отлично печататься.
Вещи, которые я пробовал:
- Файл .properties в кодировке UTF-8 с японской строкой как есть для значения. Что-то, что я прочитал, указывает на то, что Java ожидает, что файл свойств будет в собственной кодировке системы…? В любом случае это не сработало.
- Файл в кодировке по умолчанию (ISO-8859-1) и значение, сохраненное в виде экранированного Юникода, созданного программой native2ascii, входящей в состав Java. Попробовал использовать исходный файл в различных японских кодировках… SHIFT-JIS, EUC-JP, ISO-2022-JP.
Редактировать:
Я на самом деле понял это, пока печатал это, но я решил, что все равно опубликую это и отвечу на него, если это кому-нибудь поможет.
Ответ №1:
Я понял, что native2ascii предполагал (удивление), что он каждый раз преобразуется из кодировки по умолчанию моей операционной системы и, как таковой, не создает правильную экранированную строку Юникода.
Запуск native2ascii с опцией «-encoding имя_кодирования«, где имя_кодирования было именем кодировки исходного файла (в данном случае SHIFT-JIS), дал правильный результат, и все работает нормально.
У Ant также есть задача native2ascii, которая запускает native2ascii для набора входных файлов и отправляет выходные файлы туда, куда вы хотите, поэтому я смог добавить конструктор, который делает это в Eclipse, чтобы в моей исходной папке были строки в их исходной кодировке для удобства редактирования и сборки, автоматически помещает преобразованные файлы с тем же именем в выходную папку.
Ответ №2:
Начиная с JDK 1.6, в свойствах есть метод load (), который принимает считыватель. Это означает, что вы можете сохранить все файлы свойств в формате UTF-8 и прочитать их все напрямую, передав InputStreamReader для загрузки(). Я думаю, что это самое элегантное решение, но оно требует, чтобы ваше приложение работало во время выполнения Java 6.
Исторически сложилось так, что load() принимал только входной поток, и поток был декодирован как ISO-8859-1. Не системная кодировка по умолчанию, всегда ISO-8859-1. Это важно, потому что это делает возможным определенный взлом. Допустим, ваш файл свойств хранится в формате UTF-8. После извлечения свойства вы можете перекодировать его как ISO-8859-1 и снова декодировать как UTF-8, например так:
String realProp = new String(prop.getBytes("ISO-8859-1"), "UTF-8");
Это уродливо и хрупко, но это работает. Но я думаю, что лучшее решение, по крайней мере на ближайшие несколько лет,-это то, которое вы нашли: массовое преобразование файлов с помощью native2ascii с помощью инструмента сборки, такого как Ant.
Комментарии:
1. Хм, единственное, что мне нужно, это создать функциональность, отражающую способность заводских методов ResourceBundle получать точное имя файла в зависимости от локали, а не просто давать ему базовое имя и позволять ему вычислять остальное, получать входной поток и т. Д.
Ответ №3:
Альтернативный способ обработки файлов свойств: http://www.unipad.org/main/
Это редактор, который может читать/записывать файлы в формате escape в юникоде, это формат, который создает native2ascii.
Он не знает, насколько хорошо он работает с японским, я использовал его для венгерского.