codificar - ¿Configurando la codificación de caracteres Java predeterminada?
java encoding utf-8 (15)
¿Cómo configuro correctamente la codificación de caracteres predeterminada utilizada por la JVM (1.5.x) mediante programación?
He leído que -Dfile.encoding=whatever
solía ser el camino a seguir para JVM más antiguas ... No tengo ese lujo por razones que no me gustaría.
Yo he tratado:
System.setProperty("file.encoding", "UTF-8");
Y la propiedad se establece, pero no parece hacer que la llamada final 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());
Creo que un enfoque mejor que establecer el conjunto de caracteres predeterminado de la plataforma, especialmente porque parece que tiene restricciones para afectar la implementación de la aplicación, y mucho menos la plataforma, es llamar a String.getBytes("charsetName")
mucho más seguro. De esa manera su aplicación no depende de cosas que estén más allá de su control.
Personalmente, creo que String.getBytes()
debe estar en desuso, ya que ha causado serios problemas en varios casos que he visto, donde el desarrollador no tuvo en cuenta el posible cambio de caracteres predeterminado.
De la documentación de la interfaz de herramientas JVM ™ ...
Dado que no siempre se puede acceder o modificar la línea de comandos, por ejemplo, en máquinas virtuales incrustadas o simplemente máquinas virtuales lanzadas en los scripts, se proporciona una variable
JAVA_TOOL_OPTIONS
para que los agentes puedan iniciarse en estos casos.
Al establecer la variable de entorno (Windows) JAVA_TOOL_OPTIONS
en -Dfile.encoding=UTF8
, la propiedad del System
(Java) se configurará automáticamente cada vez que se inicie una JVM. Sabrá que el parámetro se ha seleccionado porque el siguiente mensaje se publicará en System.err
:
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
Desafortunadamente, la propiedad file.encoding
debe especificarse a medida que se inicia la JVM; para cuando se ingresa al método principal, la codificación de caracteres utilizada por String.getBytes()
y los constructores predeterminados de InputStreamReader
y OutputStreamWriter
se han almacenado en caché de forma permanente.
Como señala Edward Grech, en un caso especial como este, la variable de entorno JAVA_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 la propiedad file.encoding
, pero la mayoría del código en las bibliotecas principales de Java que necesitan determinar la codificación de caracteres predeterminada no usa 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 la sobrecarga del constructor o el método apropiado para especificarla.
En caso de que esté utilizando Spring Boot y quiera pasar el file.encoding
argumento. file.encoding
en JVM, debe ejecutarlo así:
mvn spring-boot:run -Drun.jvmArguments="-Dfile.encoding=UTF-8"
esto era necesario para nosotros ya que estábamos usando plantillas JTwig
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!
Establecemos dos propiedades del sistema juntas y hace que el sistema tome todo en utf8
file.encoding=UTF8
client.encoding.override=UTF-8
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". Agregue (nombre) JAVA_TOOL_OPTIONS con (valor) -Dfile.encoding = UTF8
Después de guardar, el entorno se reiniciará con la codificación UTF-8.
He intentado muchas cosas, pero el código de ejemplo aquí funciona a la perfección. Link
El quid del código es:
String s = "एक गाव में एक किसान";
String out = new String(s.getBytes("UTF-8"), "ISO-8859-1");
No está claro en lo que hace y no tiene control sobre este punto. Si puede interponer una clase de OutputStream diferente en el archivo de destino, puede usar un subtipo de OutputStream que convierte las cadenas en bytes en un conjunto de caracteres que defina, digamos 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 ser útil si aclara aquí exactamente lo que puede y no puede controlar en términos de flujo de datos y entorno de ejecución (aunque sé que a veces es más fácil decirlo que determinarlo). Buena suerte.
No puedo responder a su pregunta original, pero me gustaría ofrecerle algunos consejos: no dependa de la codificación predeterminada de 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 JVM.
Prueba esto :
new OutputStreamWriter( new FileOutputStream("Your_file_fullpath" ),Charset.forName("UTF8"))
Recientemente me topé con el sistema Notes 6.5 de una empresa local y descubrí que el correo web mostraba caracteres no identificables en una instalación de Windows localizada que no era de Zhongwen. He cavado durante varias semanas en línea, lo descubrí hace apenas 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 de UTF-8 no funcionaría en este caso.
Teníamos los mismos problemas. Intentamos metódicamente varias sugerencias de este artículo (y otras) en vano. También intentamos agregar el archivo -Difile.encoding = UTF8 y nada parecía funcionar.
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
Establecer la configuración regional correctamente en el archivo ~ / .bashrc funcionó para nosotros.
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, va a engañar a JVM, lo que pensaría que el conjunto de caracteres no está configurado y lo configurará de nuevo en UTF-8, en tiempo de ejecución.
Tras el comentario de @Caspar sobre la respuesta aceptada, la forma preferida de solucionar esto según Sun es:
"cambie la configuración regional de la plataforma subyacente antes de iniciar su programa Java".
Para ver la ventana acoplable:
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)