web-dev-qa-db-fra.com

Java encodage InputStream / charset

Exécution du code (exemple) suivant

import Java.io.*;

public class test {
    public static void main(String[] args) throws Exception {
        byte[] buf = {-27};
        InputStream is = new ByteArrayInputStream(buf);
        BufferedReader r = new BufferedReader(
                new InputStreamReader(is, "ISO-8859-1"));
        String s = r.readLine();
        System.out.println("test.Java:9 [byte] (char)" + (char)s.getBytes()[0] + 
                " (int)" + (int)s.getBytes()[0]);
        System.out.println("test.Java:10 [char] (char)" + (char)s.charAt(0) + 
                " (int)" + (int)s.charAt(0));
        System.out.println("test.Java:11 string below");
        System.out.println(s);
        System.out.println("test.Java:13 string above");
    }
}

me donne cette sortie

 test.Java:9 [octet] (char)? (int) 63 
 test.Java:10 [char] (char)? (int) 229 
 test.Java:11 chaîne en dessous de 
? 
 test.Java:13 chaîne au-dessus de 

Comment conserver la valeur d'octet correcte (-27) dans l'impression de la ligne 9? Et par conséquent recevoir la sortie attendue de la commande System.out.println(s) (å).

14
Tobbe

Si vous souhaitez conserver les valeurs byte, n'utilisez pas du tout de lecteur, idéalement. Pour représenter des données binaires arbitraires dans du texte et les reconvertir en données binaires ultérieurement, vous devez utiliser le codage base16 ou base64.

Cependant, pour expliquer ce qui se passe, lorsque vous appelez s.getBytes() qui utilise le codage de caractères par défaut, qui ne comprend apparemment pas le caractère Unicode U + 00E5.

Si vous appelez s.getBytes("ISO-8859-1") partout au lieu de s.getBytes() Je pense que vous obtiendrez la bonne valeur d'octet ... mais compter sur ISO-8859-1 pour cela est un peu sale IMO.

21
Jon Skeet

Comme indiqué, getBytes() (no-arguments) utilise le codage par défaut de la plate-forme Java, qui peut ne pas être ISO-8859-1. Il suffit de l'imprimer devrait fonctionner, à condition que votre terminal et le codage par défaut correspondent et prennent en charge le caractère. Par exemple, sur mon système, le terminal et le codage par défaut Java encoding sont tous les deux UTF-8. Le fait que vous voyez un "?" indique que le vôtre ne correspond pas ou å n'est pas pris en charge.

Si vous souhaitez encoder manuellement en UTF-8 sur votre système, procédez comme suit:

String s = r.readLine();
byte[] utf8Bytes = s.getBytes("UTF-8");

Il doit donner un tableau d'octets avec {-61, -91}.

7
Matthew Flaschen