¿Establecer la codificación de caracteres Java predeterminada?


¿Cómo puedo configurar correctamente la codificación de caracteres predeterminada utilizada por la JVM (1.5.x) ¿programáticamente?

He leído que -Dfile.encoding=whatever solía ser el camino a seguir para las JVM más antiguas... No tengo ese lujo por razones que no me gustarían.

He intentado:

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

Y la propiedad se establece, pero no parece causar que la llamada final de getBytes a continuación use 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());
Author: Bhavik Ambani, 2008-12-12

15 answers

Desafortunadamente, la propiedad file.encoding debe especificarse cuando se inicia la JVM; cuando se ingresa su método principal, la codificación de caracteres utilizada por String.getBytes() y los constructores predeterminados de InputStreamReader y OutputStreamWriter se han almacenado permanentemente en caché.

Como Edward Grech señala, en un caso especial como este, la variable de entornoJAVA_TOOL_OPTIONS se puede usar para especificar esta propiedad, pero normalmente se hace así:

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

Charset.defaultCharset() reflejará los cambios en el file.encoding propiedad, pero la mayoría del código en las bibliotecas Java principales que necesitan determinar la codificación de caracteres predeterminada no utilizan este mecanismo.

Cuando esté codificando o decodificando, puede consultar la propiedad file.encoding o Charset.defaultCharset() para encontrar la codificación predeterminada actual, y usar el método o la sobrecarga del constructor adecuados para especificarla.

 261
Author: erickson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:46

De la documentación de la Interfaz de la herramienta JVM™ {

Dado que no siempre se puede acceder a la línea de comandos ni modificarla, por ejemplo en máquinas virtuales incrustadas o simplemente máquinas virtuales lanzadas dentro de scripts, se proporciona una variable JAVA_TOOL_OPTIONS para que los agentes se puedan lanzar en estos casos.

Al establecer la variable de entorno (Windows) JAVA_TOOL_OPTIONS en -Dfile.encoding=UTF8, la propiedad (Java) System se establecerá automáticamente cada vez que se inicie una JVM. Usted sabrá que el parámetro ha sido recogió porque el siguiente mensaje será enviado a System.err:

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8

 154
Author: Edward Grech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-08 04:46:37

Tengo una forma de hacky que definitivamente funciona!!

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

De esta manera vas a engañar a JVM que pensaría que charset no está configurado y lo hará para configurarlo nuevamente a UTF-8, en tiempo de ejecución!

 55
Author: naskoos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-22 10:16:57

Creo que un mejor enfoque que establecer el conjunto de caracteres predeterminado de la plataforma, especialmente porque parece tener restricciones que afectan la implementación de la aplicación, y mucho menos la plataforma, es llamar a la mucho más segura String.getBytes("charsetName"). De esa manera, su aplicación no depende de cosas fuera de su control.

Personalmente siento que String.getBytes() debería estar en desuso, ya que ha causado graves problemas en varios casos que he visto, donde el desarrollador no tuvo en cuenta el conjunto de caracteres predeterminado posiblemente cambiante.

 36
Author: Dov Wasserman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-30 14:15:10

No puedo responder a su pregunta original, pero me gustaría ofrecerle algunos consejos't no dependa de la codificación predeterminada de la JVM. Siempre es mejor especificar explícitamente la codificación deseada (es decir, "UTF-8") en su código. De esa manera, sabe que funcionará incluso en diferentes sistemas y configuraciones de JVM.

 17
Author: Marc Novakowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-12 05:36:04

Prueba esto:

    new OutputStreamWriter( new FileOutputStream("Your_file_fullpath" ),Charset.forName("UTF8"))
 12
Author: Emmanuel.B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-20 18:09:42

Estábamos teniendo los mismos problemas. Metódicamente probamos varias sugerencias de este artículo (y otros) en vano. También intentamos agregar el-Dfile.encoding = UTF8 y nada parecía estar funcionando.

Para las personas que tienen este problema, el siguiente artículo finalmente nos ayudó a rastrear describe cómo la configuración regional puede romper unicode / UTF-8 en Java/Tomcat

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

Configurando el locale correctamente en ~/.el archivo Bashrc funcionó para nosotros.

 5
Author: D Bright,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-09 00:46:28

He intentado muchas cosas, pero el código de ejemplo aquí funciona perfecto. Link

El quid del código es:

String s = "एक गाव में एक किसान";
String out = new String(s.getBytes("UTF-8"), "ISO-8859-1");
 3
Author: Lavixu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-03 16:15:57

En caso de que estés usando Spring Boot y quieras pasar el argumento file.encoding en JVM tienes que ejecutarlo así:

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

Esto era necesario para nosotros ya que estábamos usando JTwig plantillas y el sistema operativo tenía ANSI_X3.4-1968 que descubrimos a través de System.out.println(System.getProperty("file.encoding"));

Espero que esto ayude a alguien!

 3
Author: Michail Michailidis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-23 17:01:53

No está claro sobre lo que haces y sobre lo que no tienes control en este punto. Si puede interponer una clase OutputStream diferente en el archivo de destino, podría usar un subtipo de OutputStream que convierta Cadenas en bytes bajo un conjunto de caracteres que defina, por ejemplo UTF-8 de forma predeterminada. Si el UTF-8 modificado es suficiente para sus necesidades, puede usar 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

Si este enfoque no es factible, puede ayudar si aclara aquí exactamente lo que puede y no puede controlar en términos de flujo de datos y ejecución ambiente (aunque sé que a veces es más fácil decirlo que determinarlo). Buena suerte.

 1
Author: Dov Wasserman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-16 03:59:32
mvn clean install -Dfile.encoding=UTF-8 -Dmaven.repo.local=/path-to-m2

El comando trabajó con exec-maven-plugin para resolver el siguiente error al configurar una tarea 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)
 1
Author: prabushi samarakoon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-06 08:28:28

Establecemos dos propiedades del sistema juntas y hace que el sistema tome todo en utf8

file.encoding=UTF8
client.encoding.override=UTF-8
 0
Author: lizi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-19 19:23:40

Siguiendo el comentario de @Caspar sobre la respuesta aceptada, la forma preferida de arreglar esto de acuerdo con Sun es:

"cambie la configuración regional de la plataforma subyacente antes de iniciar el programa Java."

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

Para docker ver:

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

 0
Author: Luis Muñoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-05 15:40:32

Recientemente me topé con el sistema Notes 6.5 de una compañía local y descubrí que el correo web mostraría caracteres no identificables en una instalación de Windows no localizada de Zhongwen. Han cavado durante varias semanas en línea, lo descubrió hace solo unos minutos:

En las propiedades de Java, agregue la siguiente cadena a los parámetros de tiempo de ejecución

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

La configuración UTF-8 no funcionaría en este caso.

 0
Author: midmaestro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-14 17:14:47

Estoy usando Amazon (AWS) Elastic Beanstalk y lo cambié con éxito a UTF-8.

En Elastic Beanstalk, vaya a Configuración > Software, "Propiedades del entorno". Añadir (nombre) JAVA_TOOL_OPTIONS con (valor) -Dfile.encoding = UTF8

Después de guardar, el entorno se reiniciará con la codificación UTF-8.

 0
Author: Berend Menninga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-24 08:59:03