java кодировка по умолчанию

Является ли UTF-8 кодировкой по умолчанию в Java?
Если нет, как я могу узнать, какая кодировка используется по умолчанию?

Ответов: 6

Набор символов по умолчанию для JVM — это система, в которой он запущен. Для этого нет никакого конкретного значения, и вы не должны в основном зависеть от кодировки по умолчанию, являющейся каким-либо конкретным значением.

Он может быть доступен во время выполнения через Charset.defaultCharset() , если это вам полезно, хотя на самом деле вы должны четко указать кодировку, когда сможете это сделать.

Обратите внимание, что вы можете изменить кодировку JVM по умолчанию, используя свойство confusingly named file.encoding .

Если ваше приложение особенно чувствительно к кодировкам (возможно, с использованием API-интерфейсов, подразумевающих кодировки по умолчанию), тогда вы должны явно указать это при запуске JVM на согласованное (известное) значение.

Существует три «кодировки по умолчанию»:

И кодировка InputStreamReader:
InputStreamReader.getEncoding()

Вы можете узнать больше об этом на этой странице .

Я уверен, что это специфическая реализация JVM, но я смог «повлиять» на мой файл по умолчанию jVM по умолчанию, выполнив:

(запуск java версии 1.7.0_80 на Ubuntu 12.04)

Кроме того, если вы наберете «locale» из своей консоли unix, вы увидите там больше информации.

Это будет зависящим от языка. Различная локаль, различная кодировка по умолчанию.

Как правильно установить кодировку символов по умолчанию, используемую JVM (1.5.х) программно?

Я читал, что -Dfile.encoding=whatever раньше был способ пойти для старых JVMs. У меня нет такой роскоши по причинам, в которые я не хочу вдаваться.

и свойство устанавливается, но это, похоже, не вызывает окончательный вызов getBytes ниже, чтобы использовать UTF8:

15 ответов

к сожалению, file.encoding свойство должно быть указано при запуске JVM; к моменту ввода основного метода кодировка символов, используемая String.getBytes() и конструкторы по умолчанию InputStreamReader и OutputStreamWriter постоянно кэшируется.

As Эдвард грех указывает, в частном случае, как это, переменная окружения JAVA_TOOL_OPTIONS can используется для указания этого свойства, но обычно это делается так это:

Charset.defaultCharset() будет отражать изменения file.encoding свойство, но большинство кода в основных библиотеках Java, которые должны определить кодировку символов по умолчанию, не используют этот механизм.

когда вы кодируете или декодируете, вы можете запросить file.encoding собственность или Charset.defaultCharset() чтобы найти текущую кодировку по умолчанию и использовать соответствующий метод или перегрузку конструктора, чтобы указать ее.

поскольку командная строка не всегда может быть доступна или изменена, например, во встроенных VMs или просто VMs, запущенных глубоко в сценариях, a JAVA_TOOL_OPTIONS переменная предоставляется так, что агенты могут быть запущены в этих случаях.

установив переменную среды (Windows) JAVA_TOOL_OPTIONS до -Dfile.encoding=UTF8 , (Java) System свойство будет устанавливаться автоматически при каждом запуске JVM. Вы будет знать, что параметр был выбран, потому что следующее сообщение будет опубликовано на System.err :

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8

У меня есть хакерский способ, который определенно работает!!

таким образом, вы собираетесь обмануть JVM, который будет думать, что charset не установлен и сделать это, чтобы установить его снова в UTF-8, во время выполнения!

Я думаю, что лучший подход, чем установка набора символов платформы по умолчанию, тем более, что у вас, похоже, есть ограничения на влияние на развертывание приложения, не говоря уже о платформе, — это вызвать гораздо более безопасный String.getBytes(«charsetName») . Таким образом, ваше приложение не зависит от вещей, находящихся вне его контроля.

Я лично считаю, что String.getBytes() должно быть устаревшим, так как это вызвало серьезные проблемы в ряде случаев, которые я видел, когда разработчик не учитывал значение по умолчанию кодировка, возможно, меняется.

Я не могу ответить на ваш первоначальный вопрос, но я хотел бы предложить вам несколько советов-не зависите от кодировки JVM по умолчанию. Всегда лучше явно указать желаемую кодировку (например,» UTF-8″) в вашем коде. Таким образом, вы знаете, что он будет работать даже в разных системах и конфигурациях JVM.

Очевидным ответом является использование Charset.defaultCharset() , но мы недавно выяснили, что это может быть неправильный ответ. Мне сказали, что результат отличается от реального набора символов по умолчанию, используемого классами java.io в нескольких случаях. Похоже, Java поддерживает 2 набора кодировки по умолчанию. Кто-нибудь знает о этой проблеме?

Мы смогли воспроизвести один случай отказа. Это своего рода ошибка пользователя, но она все еще может выявить основную причину всех других проблем. Вот код,

Наш сервер требует по умолчанию набор символов в Latin-1, чтобы иметь дело с некоторой смешанной кодировки (ANSI/Latin-1/UTF-8) в унаследованной протоколе. Таким образом, все наши серверы работают с этим параметром JVM,

Вот результат на Java 5,

Кто-то пытается изменить среду выполнения кодирования, установив file.encoding в коде. Мы все знаем, что это не сработает. Однако это, по-видимому, сбрасывает defaultCharset(), но это не влияет на реальную кодировку по умолчанию, используемую OutputStreamWriter.

Это ошибка или функция?

EDIT: принятый ответ показывает основную причину проблемы. В принципе, вы не можете доверять defaultCharset() в Java 5, который не является кодировкой по умолчанию, используемой классами ввода-вывода. Похоже, что Java 6 исправляет эту проблему.

Создан 17 ноя. 09 2009-11-17 13:55:45 ZZ Coder

Это странно, так как по умолчанию в Карте используется статическая переменная, которая устанавливается только один раз (в соответствии с документами — при запуске VM). Какой VM Vendor вы используете? – Bozho 17 ноя. 09 2009-11-17 14:14:45

Я смог воспроизвести это на Java 5, как на Sun/Linux, так и на Apple/OS X. – ZZ Coder 17 ноя. 09 2009-11-17 14:18:43

@ZZ Coder, я думаю, что нашел проблему. Проверьте мой обновленный ответ. – bruno conde 17 ноя. 09 2009-11-17 14:58:36

Это объясняет, почему defaultCharset() не кэширует результат. Мне все еще нужно выяснить, какова реальная кодировка по умолчанию, используемая классами ввода-вывода. Должна быть другая кодировка по умолчанию, кэшированная где-то еще. – ZZ Coder 17 ноя. 09 2009-11-17 15:17:11

@ZZ Coder, я все еще изучаю это. Единственное, что я знаю, это то, что Charset.defaulyCharset() не вызывается из sun.nio.cs.StreamEncoder в JVM 1.5. В JVM 1.6 вызывается метод Charset.defaulyCharset(), дающий ожидаемые результаты. JVM 1.5 реализация StreamEncoder кэширует предыдущую кодировку. – bruno conde 17 ноя. 09 2009-11-17 15:36:56

Хорошо. @ZZ Coder проверить мой обновленный ответ. – bruno conde 17 ноя. 09 2009-11-17 16:07:53

6 ответов

Это действительно странно . После установки по умолчанию Charset кэшируется и не изменяется, пока класс находится в памяти. Установка «file.encoding» объекта с System.setProperty(«file.encoding», «Latin-1»); ничего не делает. Каждый раз, когда вызывается Charset.defaultCharset() , он возвращает кэшированную кодировку.

Вот мои результаты:

Я использую JVM 1.6, хотя.

(обновление)

Ok. Я воспроизвел вашу ошибку с помощью JVM 1.5.

Рассматривая исходный код 1.5, кешированная кодировка по умолчанию не установлена. Я не знаю, если это ошибка или нет, но 1.6 изменений этой реализации и использует кэшированный кодовый:

При установке кодировка файла до file.encoding=Latin-1 при следующем вызове Charset.defaultCharset() , что происходит, потому что кешированная кодировка по умолчанию не установлена, она попытается найти соответствующую кодировку для имени Latin-1 . Это имя не найдено, потому что оно неверно, и возвращает значение по умолчанию UTF-8 .

А почему классы ввода-вывода, такие как OutputStreamWriter возвращение неожиданный результат,
осуществление sun.nio.cs.StreamEncoder (ведьма используется этими классами IO) отличается также и для виртуальной машины Java 1.5 и 1.6 JVM. Реализация JVM 1.6 основана на методе Charset.defaultCharset() , чтобы получить кодировку по умолчанию, если она не предоставляется классам ввода-вывода. В реализации JVM 1.5 используется другой метод Converters.getDefaultEncodingName(); , чтобы получить кодировку по умолчанию. Этот метод использует свой собственный кэш кодировки по умолчанию, который устанавливается при инициализации виртуальной машины Java:

Но я согласен с замечаниями. Вы не должны полагаться на это имущество. Это деталь реализации.

Создан 17 ноя. 09 2009-11-17 14:25:00 bruno conde

Источник: computermaker.info

Техника и Гаджеты
Добавить комментарий