web-dev-qa-db-fra.com

Définition du codage de caractères Java par défaut

Comment définir correctement le codage de caractères par défaut utilisé par la machine virtuelle Java (1.5.x) par programme?

J'ai lu que -Dfile.encoding=whatever était le chemin à suivre pour les anciennes JVM ... Je n'ai pas ce luxe pour des raisons qui m'empêcheraient d'entrer.

J'ai essayé:

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

Et la propriété est définie, mais elle ne semble pas obliger le dernier appel getBytes à utiliser 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());
335
Scott T

Malheureusement, la propriété file.encoding doit être spécifiée au démarrage de la machine virtuelle Java. au moment où vous entrez votre méthode principale, le codage de caractères utilisé par String.getBytes() et les constructeurs par défaut de InputStreamReader et OutputStreamWriter ont été mis en cache de manière permanente.

Comme Edward Grech souligne, dans un cas spécial comme celui-ci, la variable d'environnement Java_TOOL_OPTIONS peut être utilisée pour spécifiez cette propriété, mais cela se fait normalement comme ceci:

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

Charset.defaultCharset() reflétera les modifications apportées à la propriété file.encoding, mais la plupart du code des bibliothèques principales Java devant déterminer le codage de caractères par défaut n'utilise pas ce mécanisme.

Lors du codage ou du décodage, vous pouvez interroger la propriété file.encoding ou Charset.defaultCharset() pour rechercher le codage par défaut actuel et utiliser la méthode ou la surcharge de constructeur appropriée pour le spécifier.

287
erickson

À partir de la interface JVM ™ Tool documentation…

Etant donné que la ligne de commande ne peut pas toujours être consultée ou modifiée, par exemple dans les ordinateurs virtuels intégrés ou simplement dans les ordinateurs virtuels lancés profondément dans des scripts, une variable Java_TOOL_OPTIONS est fournie afin que les agents puissent être lancés dans ces cas.

En définissant la variable d'environnement (Windows) Java_TOOL_OPTIONS sur -Dfile.encoding=UTF8, la propriété (Java) System est définie automatiquement à chaque démarrage d'une machine virtuelle. Vous saurez que le paramètre a été récupéré car le message suivant sera envoyé à System.err:

Picked up Java_TOOL_OPTIONS: -Dfile.encoding=UTF8

161
Edward Grech

J'ai un moyen hacky qui fonctionne vraiment!

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

De cette façon, vous allez tromper JVM qui penserait que le jeu de caractères n'est pas défini et le redéfinit sur UTF-8, au moment de l'exécution!

63
naskoos

Je pense qu'une meilleure approche que de définir le jeu de caractères par défaut de la plate-forme, d'autant plus que vous semblez avoir des restrictions pour affecter le déploiement de l'application, sans parler de la plate-forme, consiste à appeler le beaucoup plus sûr String.getBytes("charsetName"). Ainsi, votre application ne dépend pas d'éléments indépendants de sa volonté.

Personnellement, j'estime que String.getBytes() devrait être déconseillé, car cela a causé de graves problèmes dans un certain nombre de cas que j'ai vus, où le développeur n'a pas tenu compte du jeu de caractères par défaut éventuellement modifié.

37
Dov Wasserman

Je ne peux pas répondre à votre question initiale, mais j'aimerais vous donner quelques conseils. Ne dépendez pas du codage par défaut de la machine virtuelle. Il est toujours préférable de spécifier explicitement le codage souhaité ("UTF-8") dans votre code. De cette façon, vous savez que cela fonctionnera même sur différents systèmes et configurations JVM.

17
Marc Novakowski

Essaye ça :

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

Nous avions les mêmes problèmes. Nous avons méthodiquement essayé plusieurs suggestions de cet article (et d’autres) en vain. Nous avons également essayé d'ajouter le -Dfile.encoding=UTF8 et rien ne semblait fonctionner.

Pour les personnes confrontées à ce problème, l'article suivant nous a enfin aidé à comprendre comment le paramètre régional peut décomposer unicode/UTF-8 dans Java/Tomcat

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

Définir les paramètres régionaux correctement dans le fichier ~/.bashrc a fonctionné pour nous.

5
D Bright

Si vous utilisez Spring Boot et souhaitez passer l'argument file.encoding dans la machine virtuelle Java, vous devez l'exécuter comme suit:

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

cela était nécessaire pour nous puisque nous utilisions JTwig modèles et que le système d’exploitation possédait ANSI_X3.4-1968 que nous avions découvert par System.out.println(System.getProperty("file.encoding"));

J'espère que ça aide quelqu'un!

4
Michail Michailidis

J'ai essayé beaucoup de choses, mais l'exemple de code ici fonctionne parfaitement. Lien

Le noeud du code est:

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

cette commande fonctionnait avec exec-maven-plugin pour résoudre l’erreur suivante lors de la configuration d’une tâche 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

Pas clair sur ce que vous faites et n'avez pas de contrôle sur ce point. Si vous pouvez interposer une classe OutputStream différente dans le fichier de destination, vous pouvez utiliser un sous-type de OutputStream qui convertit les chaînes en octets sous un jeu de caractères que vous définissez, par exemple UTF-8. Si UTF-8 modifié suffit à vos besoins, vous pouvez utiliser 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 cette approche n'est pas réalisable, il peut être utile de clarifier ici exactement ce que vous pouvez et ne pouvez pas contrôler en termes de flux de données et d'environnement d'exécution (bien que je sache que c'est parfois plus facile à dire qu'à déterminer). Bonne chance.

1
Dov Wasserman

Après les commentaires de @Caspar sur la réponse acceptée, le moyen préféré de résoudre ce problème selon Sun est:

"modifier les paramètres régionaux de la plate-forme sous-jacente avant de démarrer votre programme Java."

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

Pour docker, voir:

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

0
Luis Muñoz

Mon équipe a rencontré le même problème sur des machines Windows .. puis est parvenue à le résoudre de deux manières:

a) Définir la variable d'environnement (même dans les préférences système Windows)

Java_TOOL_OPTIONS
- Dfile.encoding = UTF8

b) Introduisez l'extrait suivant dans votre pom.xml:

 -Dfile.encoding=UTF-8 

DANS

 <jvmArguments>
 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001
 -Dfile.encoding=UTF-8
 </jvmArguments>
0
JacobTheKnitter

Récemment, je suis tombé sur le système Notes 6.5 d'une entreprise locale et j'ai découvert que le webmail afficherait des caractères non identifiables sur une installation Windows autre que celle de Zhongwen. J'ai creusé pendant plusieurs semaines en ligne, a découvert il y a quelques minutes à peine:

Dans les propriétés Java, ajoutez la chaîne suivante à Paramètres d'exécution.

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

Le réglage UTF-8 ne fonctionnerait pas dans ce cas.

0
midmaestro

J'utilise Amazon (AWS) Elastic Beanstalk et j'ai réussi à le remplacer par UTF-8.

Dans Elastic Beanstalk, accédez à Configuration> Logiciel, "Propriétés de l'environnement". Ajoutez (nom) Java_TOOL_OPTIONS avec (valeur) -Dfile.encoding = UTF8

Après la sauvegarde, l’environnement redémarre avec le codage UTF-8.

0
Berend Menninga

Nous définissons deux propriétés système ensemble, ce qui rend le système tout en utf8

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