Установка кодировки символов Java по умолчанию? - PullRequest
331 голосов
/ 12 декабря 2008

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

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

Я пробовал:

System.setProperty("file.encoding", "UTF-8");

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

    System.setProperty("file.encoding", "UTF-8");

    byte inbytes[] = new byte[1024];

    FileInputStream fis = new FileInputStream("response.txt");
    fis.read(inbytes);
    FileOutputStream fos = new FileOutputStream("response-2.txt");
    String in = new String(inbytes, "UTF8");
    fos.write(in.getBytes());

Ответы [ 15 ]

283 голосов
/ 12 декабря 2008

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

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

java -Dfile.encoding=UTF-8 … com.x.Main

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

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

158 голосов
/ 08 марта 2009

Из интерфейса инструмента JVM ™ документация ...

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

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

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8

61 голосов
/ 20 февраля 2013

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

System.setProperty("file.encoding","UTF-8");
Field charset = Charset.class.getDeclaredField("defaultCharset");
charset.setAccessible(true);
charset.set(null,null);

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

37 голосов
/ 12 декабря 2008

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

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

17 голосов
/ 12 декабря 2008

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

12 голосов
/ 20 января 2012

Попробуйте это:

    new OutputStreamWriter( new FileOutputStream("Your_file_fullpath" ),Charset.forName("UTF8"))
5 голосов
/ 09 января 2014

У нас были те же проблемы. Мы методично попробовали несколько предложений из этой статьи (и других) безрезультатно. Мы также попытались добавить -Dfile.encoding = UTF8, но ничего не получалось.

Для людей, у которых возникла эта проблема, следующая статья, наконец, помогла нам отследить, описывает, как настройка локали может сломать Unicode / UTF-8 в Java / Tomcat

http://www.jvmhost.com/articles/locale-breaks-unicode-utf-8-java-tomcat

Правильная настройка локали в файле ~ / .bashrc сработала для нас.

4 голосов
/ 23 февраля 2018

Если вы используете Spring Boot и хотите передать аргумент file.encoding в JVM, вы должны запустить его следующим образом:

mvn spring-boot:run -Drun.jvmArguments="-Dfile.encoding=UTF-8"

это было необходимо для нас, так как мы использовали JTwig шаблоны, а в операционной системе было ANSI_X3.4-1968, что мы обнаружили через System.out.println(System.getProperty("file.encoding"));

Надеюсь, это кому-нибудь поможет!

3 голосов
/ 03 июля 2014

Я много чего перепробовал, но пример кода здесь работает отлично. Ссылка

Суть кода:

String s = "एक गाव में एक किसान";
String out = new String(s.getBytes("UTF-8"), "ISO-8859-1");
1 голос
/ 06 марта 2018
mvn clean install -Dfile.encoding=UTF-8 -Dmaven.repo.local=/path-to-m2

Команда работала с exec-maven-plugin для устранения следующей ошибки при настройке задачи jenkins.

Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512m; support was removed in 8.0
Error occurred during initialization of VM
java.nio.charset.IllegalCharsetNameException: "UTF-8"
    at java.nio.charset.Charset.checkName(Charset.java:315)
    at java.nio.charset.Charset.lookup2(Charset.java:484)
    at java.nio.charset.Charset.lookup(Charset.java:464)
    at java.nio.charset.Charset.defaultCharset(Charset.java:609)
    at sun.nio.cs.StreamEncoder.forOutputStreamWriter(StreamEncoder.java:56)
    at java.io.OutputStreamWriter.<init>(OutputStreamWriter.java:111)
    at java.io.PrintStream.<init>(PrintStream.java:104)
    at java.io.PrintStream.<init>(PrintStream.java:151)
    at java.lang.System.newPrintStream(System.java:1148)
    at java.lang.System.initializeSystemClass(System.java:1192)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...