Установка кодировки символов Java по умолчанию?

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

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

Я пробовал:

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 ответов


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

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

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

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

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


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

поскольку командная строка не всегда может быть доступна или изменена, например, во встроенных 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


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

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

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


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

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


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


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

    new OutputStreamWriter( new FileOutputStream("Your_file_fullpath" ),Charset.forName("UTF8"))

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

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

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

установка языкового стандарта правильно в~/.файл bashrc работал на нас.


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

суть кода:

String s = "एक गाव में एक किसान";
String out = new String(s.getBytes("UTF-8"), "ISO-8859-1");

в случае, если вы используете 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"));

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


не ясно, что вы делаете и не контролируете на данный момент. Если вы можете вставить другой класс OutputStream в целевой файл, вы можете использовать подтип OutputStream, который преобразует строки в байты под заданной вами кодировкой, например UTF-8 по умолчанию. Если измененного UTF-8 достаточно для ваших нужд, вы можете использовать DataOutputStream.writeUTF(String):

byte inbytes[] = new byte[1024];
FileInputStream fis = new FileInputStream("response.txt");
fis.read(inbytes);
String in = new String(inbytes, "UTF8");
DataOutputStream out = new DataOutputStream(new FileOutputStream("response-2.txt"));
out.writeUTF(in); // no getBytes() here

Если этот подход неосуществим, это может помочь, если вы уточните здесь, что именно вы можете и не можете контролировать с точки зрения данных среда потока и выполнения (хотя я знаю, что иногда это легче сказать, чем определить). Удача.


mvn clean install -Dfile.encoding=UTF-8 -Dmaven.repo.local=/path-to-m2

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

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)

мы устанавливаем там два системных свойства вместе, и это заставляет систему принимать все в utf8

file.encoding=UTF8
client.encoding.override=UTF-8

после комментария @ Caspar на принятый ответ предпочтительный способ исправить это в соответствии с Sun:

" измените языковой стандарт базовой платформы перед запуском программы Java."

http://bugs.java.com/view_bug.do?bug_id=4163515

для настройки см.:

http://jaredmarkell.com/docker-and-locales/


недавно я наткнулся на систему Notes 6.5 местной компании и узнал, что веб-почта покажет неопознанные символы на не-Zhongwen локализованной установке Windows. Копали несколько недель в интернете, выяснили это всего несколько минут назад:

в свойствах Java добавьте следующую строку в параметры среды выполнения

-Dfile.encoding=MS950 -Duser.language=zh -Duser.country=TW -Dsun.jnu.encoding=MS950

кодировка UTF-8 не будет работать в этом случае.


Я использую Amazon (AWS) Elastic Beanstalk и успешно изменил его на UTF-8.

в Elastic Beanstalk перейдите в раздел Конфигурация > программное обеспечение, "свойства среды". Добавить (имя) JAVA_TOOL_OPTIONS с (значение) - Dfile.кодировка=utf8 в

после сохранения среда перезапустится с кодировкой UTF-8.