it-swarm.dev

Definindo a codificação padrão de caracteres Java?

Como faço para definir corretamente a codificação de caracteres padrão usada pela JVM (1.5.x) programaticamente?

Eu li que -Dfile.encoding=whatever costumava ser o caminho a percorrer para as JVMs mais antigas ... Eu não tenho esse luxo por razões que eu não entendo.

Eu tentei:

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

E a propriedade é configurada, mas parece que a chamada getBytes final abaixo não usa o 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());
331
Scott T

Infelizmente, a propriedade file.encoding deve ser especificada conforme a inicialização da JVM; no momento em que seu método principal é inserido, a codificação de caracteres usada por String.getBytes() e os construtores padrão de InputStreamReader e OutputStreamWriter foram permanentemente armazenados em cache.

Como Edward Grech aponta, em um caso especial como este, a variável de ambiente Java_TOOL_OPTIONS pode ser usada para especificar esta propriedade, mas normalmente é feito assim:

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

Charset.defaultCharset() refletirá as alterações na propriedade file.encoding, mas a maior parte do código nas principais bibliotecas Java que precisam determinar a codificação de caracteres padrão não usa esse mecanismo.

Quando você estiver codificando ou decodificando, poderá consultar a propriedade file.encoding ou Charset.defaultCharset() para localizar a codificação padrão atual e usar o método apropriado ou a sobrecarga do construtor para especificá-la.

283
erickson

Na Interface da Ferramenta JVM ™ documentação…

Como a linha de comando nem sempre pode ser acessada ou modificada, por exemplo, em VMs incorporadas ou simplesmente VMs lançadas dentro de scripts, uma variável Java_TOOL_OPTIONS é fornecida para que os agentes possam ser iniciados nesses casos.

Ao configurar a variável de ambiente (Windows) Java_TOOL_OPTIONS para -Dfile.encoding=UTF8, a propriedade (Java) System será configurada automaticamente toda vez que uma JVM for iniciada. Você saberá que o parâmetro foi selecionado porque a seguinte mensagem será postada em System.err:

Picked up Java_TOOL_OPTIONS: -Dfile.encoding=UTF8

158
Edward Grech

Eu tenho um jeito hacker que definitivamente funciona !!

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

Desta forma, você vai enganar a JVM, que acha que o conjunto de caracteres não está definido e torná-lo para configurá-lo novamente para UTF-8, em tempo de execução!

61
naskoos

Eu acho que uma abordagem melhor do que definir o conjunto de caracteres padrão da plataforma, especialmente porque você parece ter restrições em afetar a implantação do aplicativo, sem falar na plataforma, é chamar a String.getBytes("charsetName") muito mais segura. Dessa forma, seu aplicativo não depende de coisas além do seu controle.

Eu pessoalmente sinto que String.getBytes() deve ser preterido, pois causou sérios problemas em vários casos que eu vi, onde o desenvolvedor não levou em conta o charset padrão que possivelmente está mudando.

37
Dov Wasserman

Não posso responder à sua pergunta original, mas gostaria de oferecer alguns conselhos - não dependa da codificação padrão da JVM. É sempre melhor especificar explicitamente a codificação desejada (ou seja, "UTF-8") em seu código. Dessa forma, você sabe que funcionará mesmo em diferentes sistemas e configurações de JVM.

17
Marc Novakowski

Tente isto:

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

Nós estávamos tendo os mesmos problemas. Nós metodicamente tentamos várias sugestões deste artigo (e outros) sem sucesso. Nós também tentamos adicionar o -Dfile.encoding = UTF8 e nada parecia estar funcionando.

Para as pessoas que estão tendo esse problema, o seguinte artigo finalmente nos ajudou a rastrear descreve como a configuração de localidade pode quebrar o unicode/UTF-8 no Java/Tomcat

http://www.jvmhost.com/articles/locale-breaks-unicode-utf-8-Java-Tomcat

Definir o local corretamente no arquivo ~/.bashrc funcionou para nós.

5
D Bright

Caso você esteja usando o Spring Boot e queira passar o argumento file.encoding na JVM você tem que rodar assim:

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

isso era necessário para nós, já que estávamos usando modelos JTwig e o sistema operacional tinha ANSI_X3.4-1968 que descobrimos por meio de System.out.println(System.getProperty("file.encoding"));

Espero que isso ajude alguém!

4
Michail Michailidis

Eu tentei muitas coisas, mas o código de exemplo aqui funciona perfeito. Link

O ponto crucial do código é:

String s = "एक गाव में एक किसान";
String out = new String(s.getBytes("UTF-8"), "ISO-8859-1");
3
Lavixu
mvn clean install -Dfile.encoding=UTF-8 -Dmaven.repo.local=/path-to-m2

o comando funcionou com o exec-maven-plugin para resolver o seguinte erro ao configurar uma tarefa 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
prabushi samarakoon

Não é claro sobre o que você faz e não tem controle sobre este ponto. Se você puder interpor uma classe OutputStream diferente no arquivo de destino, poderá usar um subtipo de OutputStream que converte Strings em bytes em um conjunto de caracteres que você define, por exemplo, UTF-8. Se o UTF-8 modificado for suficiente para as suas necessidades, você pode 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

Se essa abordagem não for viável, pode ajudar se você esclarecer exatamente o que pode e não pode controlar em termos de fluxo de dados e ambiente de execução (embora eu saiba que às vezes é mais fácil dizer do que determinar). Boa sorte.

1
Dov Wasserman

Após o comentário do @Caspar sobre a resposta aceita, a maneira preferida de corrigir isso de acordo com a Sun é:

"altere o código de idioma da plataforma subjacente antes de iniciar seu programa Java."

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

Para docker, consulte:

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

0
Luis Muñoz

Recentemente, esbarrei no sistema Notes 6.5 de uma empresa local e descobri que o webmail mostrava caracteres não identificáveis ​​em uma instalação Windows local não-Zhongwen. Pesquisei por várias semanas on-line, descobri apenas alguns minutos atrás:

Nas propriedades Java, inclua a sequência a seguir em Parâmetros de tempo de execução

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

A configuração do UTF-8 não funcionaria nesse caso.

0
midmaestro

Estou usando o Amazon (AWS) Elastic Beanstalk e o alterei com sucesso para UTF-8.

No Elastic Beanstalk, vá para Configuração> Software, "Propriedades do ambiente". Inclua (nome) Java_TOOL_OPTIONS com (value) -Dfile.encoding = UTF8

Depois de salvar, o ambiente será reiniciado com a codificação UTF-8.

0
Berend Menninga

Estabelecemos duas propriedades de sistema juntas e isso faz com que o sistema leve tudo para o utf8

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