OVH Cloud OVH Cloud

recuperer le charset par defaut

4 réponses
Avatar
Bounz
bonjour,

j'essaye de trouver un moyer de connaitre l'encodage par defaut en java.
Par exemple quand on cree une InputStream, quel est l'encodage utilise.

J'ai trouve cette methode:

String encname = null;
try {
FileWriter filewriter = new FileWriter("out");
encname = filewriter.getEncoding();
filewriter.close();
return encname;
}
catch (IOException e) {
e.printStackTrace();
}

Mais elle me semble un peu artificielle, n'y a-t'il pas un moyen plus
propre de connaitre le charset par defaut?
En introspectant les source?

Merci,

Antoine Brun

4 réponses

Avatar
Yves Martin
Bounz writes:

j'essaye de trouver un moyer de connaitre l'encodage par defaut en
java. Par exemple quand on cree une InputStream, quel est
l'encodage utilise.


Bonjour,

Un stream qui manipule le flux comme des caractères (peu importe sa
nature - File, Socket, ...) peut être construit avec l'encoding en
paramètre. Voir InputStreamReader/OutputStreamWriter chargés de la
conversion octet <-> caractère Unicode en fonction de l'encoding.

Si ce paramètre n'est pas fourni, c'est la valeur de la propriété
système file.encoding qui est utilisé. (System.getProperty)

En version 1.4, voir aussi java.nio.charset.Charset

Autres infos utiles: Un source avec des caractères spéciaux peut être
compilé avec l'option "-encoding" de Javac pour que les accents
soient correctement codés en Unicode dans les .class. Il faut aussi
savoir que tout caractère est manipulé en interne en Unicode par
Java, sauf lors des entrées/sorties où l'encoding spécifié (par
défaut file.encoding) est utilisé pour convertir vers du 8 bits
(Cp???? de Win32 ou iso-latin-1 sur Solaris par exemple)

A+
--
Yves Martin

Avatar
Bounz
Yves Martin wrote:
Bounz writes:


j'essaye de trouver un moyer de connaitre l'encodage par defaut en
java. Par exemple quand on cree une InputStream, quel est
l'encodage utilise.



Bonjour,


merci pour ces informations, j'ai encore un ou deux questions

dans le cas suivant:

String str = new String(toto);
OutputStream out = new OutputStream();
out.write(str.getBytes());

quel est l'encodage utilise pour creer out?
est-ce celui specifie par la property file.encoding?

Antoine


Avatar
Yves Martin
Bounz writes:

merci pour ces informations, j'ai encore un ou deux questions dans
le cas suivant:

String str = new String(toto);
OutputStream out = new OutputStream();
out.write(str.getBytes());

quel est l'encodage utilise pour creer out?
est-ce celui specifie par la property file.encoding?


Question piège ? Tu me testes pour voir si je réponds juste sans
faire de tests ?

Je me lance: normalement le tableau de bytes de String est en
Unicode, donc le fichier contiendra ce tableau.

Ton exemple utilise OutputStream qui ne manipule par les caractères,
il n'y pas de conversion d'encoding à ce niveau: un byte est un byte
(ce n'est pas un caractère quoi)

Si tu veux écrire du texte - donc avec traitement de l'encoding - tu
dois utiliser OutputStreamWriter, et dans ce cas, l'encoding par
défaut est file.encoding - à moins de le spécifier dans le
constructeur du Writer.

Allez, soyons sérieux: j'ai fait le test dans BeanShell:

bsh % FileOutputStream fos = new FileOutputStream("/home/yma/java_test.dat");
bsh % String s = new String("Ma string favorite avec accénts !");
bsh % fos.write(s.getBytes());
bsh % fos.flush();
bsh % fos.close();

Contenu du fichier:

yma ~> hexdump -C java_test.dat
00000000 4d 61 20 73 74 72 69 6e 67 20 66 61 76 6f 72 69 |Ma string favori|
00000010 74 65 20 61 76 65 63 20 61 63 63 e9 6e 74 73 20 |te avec accénts |
00000020 21 |!|

Je me suis donc trompé... en partie. Une lecture de la doc de
String.getBytes() explique pourquoi j'ai du iso-latin-1 au lieu de
l'Unicode.

L'OutputStream ne fait pas de conversion d'encoding mais
String.getBytes le fait ! Donc le tableau de bytes n'est pas en
Unicode comme le stockage interne de la String mais en iso-latin-1
(file.encoding sur mon Linux)

Si je veux ma String en Unicode - j'y tiens ;)

bsh % FileOutputStream fos = new FileOutputStream("/home/yma/java_test2.dat");
bsh % String s = new String("Ma string favorite avec accénts !");
bsh % fos.write(s.getBytes("unicode"));
bsh % fos.flush();
bsh % fos.close();

yma ~> hexdump -C java_test2.dat
00000000 ff fe 4d 00 61 00 20 00 73 00 74 00 72 00 69 00 |ÿþM.a. .s.t.r.i.|
00000010 6e 00 67 00 20 00 66 00 61 00 76 00 6f 00 72 00 |n.g. .f.a.v.o.r.|
00000020 69 00 74 00 65 00 20 00 61 00 76 00 65 00 63 00 |i.t.e. .a.v.e.c.|
00000030 20 00 61 00 63 00 63 00 e9 00 6e 00 74 00 73 00 | .a.c.c.é.n.t.s.|
00000040 20 00 21 00 | .!.|

Bien sur, pour relire ce fichier, je dois utiliser un FileReader en
spécifiant l'encoding "unicode" sinon je ne retrouverai pas ma
chaîne. Car par défaut il pense que c'est de l'iso-latin-1 !


En conclusion:

Il ne faut pas manipuler du binaire dans des String ou des tableaux
char[] car les conversions d'encoding risquent de modifier les
valeurs - dans ce cas, il faut utiliser des InputStream/OutputStream
et leur correspondant FileInputStream/FileOutputStream et byte[]

Pour manipuler des caractères, il faut éviter les tableaux byte[]
sauf à être sur de savoir quel encodage a été utilisé pour convertir
les caractères lors de la construction du tableau de byte[]. Les
outils à utiliser dans ce cas sont:
InputStreamReader/OutputStreamWriter et correspondants
FileReader/FileWriter avec des char[] ou des String - en configurant
file.encoding ou en spécifiant l'encodage dans les constructeurs.

--
Yves Martin

Avatar
Bounz
Yves Martin wrote:
Bounz writes:


merci pour ces informations, j'ai encore un ou deux questions dans
le cas suivant:

String str = new String(toto);
OutputStream out = new OutputStream();
out.write(str.getBytes());

quel est l'encodage utilise pour creer out?
est-ce celui specifie par la property file.encoding?



Question piège ? Tu me testes pour voir si je réponds juste sans
faire de tests ?


merci pour toutes ces information.
ce n'etaient pas des questions pieges ;-)
en fait si j'insiste c'est que l'on me demande quel est l'encodage par
defaut en me suggerant de regarder les sources pour le savoir.