Java utf 8 encoding linux

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

Как правильно настроить кодировку по умолчанию, используемую программным обеспечением 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()); 

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

может быть, неуместный вопрос, но есть ли разница, когда UTF8 установлен с «UTF8», «UTF-8» или «utf8». Недавно я обнаружил, что контейнеры IBM WAS 6.1 EJB и WEB по-разному обрабатывают (с учетом регистра) строки, используемые для определения кодировки.

Просто деталь, но: предпочитаю UTF-8 UTF8 (только первый стандарт). Это все еще применяется в 2012 году .

@erickson Мне все еще не ясно с запросом, не правда ли, что file.encoding уместен, когда используются символьные потоки ввода / вывода (все подклассы class Reader & class Writer )? Поскольку class FileInputStream является байтовым потоком ввода / вывода, так почему же следует заботиться о наборе символов в class FileInputStream потоке ввода / вывода?

15 ответов

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

Читайте также:  Using bool in python

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

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

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

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

Для полноты я хотел бы добавить, что с небольшой хитростью вы можете перейти к фактически используемой кодировке по умолчанию (как кешируется), благодаря Гари Кронину: byte [] byteArray = <'a'>; InputStream inputStream = new ByteArrayInputStream (byteArray); InputStreamReader reader = new InputStreamReader (inputStream); String defaultEncoding = reader.getEncoding (); lists.xcf.berkeley.edu/lists/advanced-java/1999-October/.

JDK-4163515 содержит дополнительную информацию о настройке file.encoding .encoding sysprop после запуска JVM.

Я почесал голову, потому что эта команда не работала на Windows, Linux и Mac отлично . затем я поместил «вокруг значения, как это: java -D» file.encoding = UTF-8 «-jar

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

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

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8

Привет, Эдвард Греч. Благодарю за решение. Это было решено моей проблемой в другом сообщении на форуме. stackoverflow.com/questions/14814230/.

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

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

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

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

Хотя я не поняла, что это, у меня все работает отлично! Благодарю. Надеюсь, это не создает новых проблем для моего приложения. Ура!

Это сработало для меня, но основная проблема заключалась в том, что ssh-соединения вращались, или jars неправильно установили свой LC_ * (в профиле).

JDK9 больше не одобряет этот взлом. WARNING: An illegal reflective access operation has occurred • WARNING: Illegal reflective access by [..] • WARNING: Please consider reporting this to the maintainers of [..] • WARNING: Use —illegal-access=warn to enable warnings of further illegal reflective access operations • WARNING: All illegal access operations will be denied in a future release

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

Проблема @sleske в том, что у java должен быть способ переопределить это, но, увы, нет, так что это хороший ответ, потому что это ЕДИНСТВЕННЫЙ ответ

@Enerccio: Можно утверждать, должен ли Java «иметь» способ установить это — можно также утверждать, что разработчики «должны» явно указывать кодировку, когда это уместно. В любом случае, это решение потенциально может вызвать серьезные проблемы в долгосрочной перспективе, следовательно, предостережение «только для экстренного использования». На самом деле, даже экстренное использование сомнительно, потому что есть поддерживаемый способ сделать это, установив JAVA_TOOL_OPTIONS, как объяснено в другом ответе.

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

@Enerccio: Если это решение работает, использование JAVA_TOOL_OPTIONS также должно работать и на самом деле является поддерживаемым решением.

Для меня просто установка системного свойства помогла решить мою проблему с кодировкой, в которой среда IDE использовала UTF-8 а JAR файл представлял собой системную кодировку по умолчанию, которая приводила к ошибкам в строках пакета ресурсов.

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

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

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

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

@MichaelBorgwardt «тогда кодирование платформы по умолчанию — ваше лучшее предположение», вы, похоже, советуете, что изменение по умолчанию — не очень хорошая идея. Вы имеете в виду, использовать везде, где это возможно, явное кодирование, используя предоставленное по умолчанию значение, когда больше ничего невозможно?

@Raedwald: да, это то, что я имел в виду. Кодировка платформы по умолчанию (по крайней мере на компьютере конечного пользователя) обычно используется пользователями в локали, на которую настроена система. Это информация, которую вы должны использовать, если у вас нет более качественной (т.е. специфичной для документа) информации.

@MichaelBorgwardt Ерунда. Используйте библиотеку для автоматического определения входной кодировки и сохраните как Unicode с BOM. Это единственный способ справиться с кодовым адом и бороться с ним.

Я думаю, что вы двое не на одной странице. Майкл говорит о декодировании, а Рэдвальд, вы говорите об обработке после декодирования.

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

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

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

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

Если вы используете 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»));

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

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

String s = "एक गाव में एक किसान"; String out = new String(s.getBytes("UTF-8"), "ISO-8859-1"); 
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.(OutputStreamWriter.java:111) at java.io.PrintStream.(PrintStream.java:104) at java.io.PrintStream.(PrintStream.java:151) at java.lang.System.newPrintStream(System.java:1148) at java.lang.System.initializeSystemClass(System.java:1192) 

Не понятно, что вы делаете и не контролируете на этом этапе. Если вы можете вставить другой файл 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 

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

DataInputStream и DataOutputStream являются классами специального назначения, которые никогда не должны использоваться с простыми текстовыми файлами. Используемые ими модифицированные UTF-8 несовместимы с реальными UTF-8. Кроме того, если ОП мог использовать ваше решение, он мог бы также использовать правильный инструмент для этой работы: OutputStreamWriter.

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

В эластичном бобовом стебле перейдите в «Конфигурация > Программное обеспечение», «Свойства среды». Добавить (имя) JAVA_TOOL_OPTIONS с (значением) -Dfile.encoding = UTF8

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

Источник

Оцените статью