2016-01-21 2 views
12

Quindi un 'carattere' in Java è 2 byte. (Possono essere verificati da here.)In che modo Java si adatta a un carattere Unicode da 3 byte in un tipo di carattere?

ho questo codice di esempio:

public class FooBar { 
    public static void main(String[] args) { 
     String foo = "€"; 
     System.out.println(foo.getBytes().length); 
     final char[] chars = foo.toCharArray(); 
     System.out.println(chars[0]); 
    } 
} 

E l'uscita è la seguente:

3 
€ 

La mia domanda è, come ha fatto Java montare un 3 byte carattere in un tipo di dati char? BTW, Sto facendo funzionare l'applicazione con il parametro: -Dfile.encoding = UTF-8

Anche se modifico il codice un po 'oltre e aggiungere le seguenti istruzioni:

File baz = new File("baz.txt"); 
final DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(baz)); 
dataOutputStream.writeChar(chars[0]); 
dataOutputStream.flush(); 
dataOutputStream.close(); 

il file finale "baz .txt "sarà solo 2 byte e non mostrerà il carattere corretto anche se lo considero come un file UTF-8.

Modifica 2: Se apro il file "baz.txt" con la codifica UTF-16 BE, vedrò il carattere € bene nel mio editor di testo, il che ha senso immagino.

+3

Java utilizza internamente UTF-16. Vedi http://stackoverflow.com/questions/9699071/what-is-the-javas-internal-represention-for-string-modified-utf-8-utf-16 –

+0

Char non è un personaggio; è meno - che è uno dei maggiori problemi con Java. Vedi utf8everywhere.org per una spiegazione completa su come funziona. –

risposta

8

String.getBytes() restituisce i byte utilizzando la codifica dei caratteri predefinita della piattaforma che non corrisponde alla rappresentazione interna.

Java utilizza 2 byte in ram per ogni char, quando i caratteri sono "serializzati" utilizzando UTF-8, possono produrre uno, due o tre byte nell'array di byte risultante, è così che funziona la codifica UTF-8.

L'esempio di codice utilizza UTF-8. Le stringhe Java sono codificate in memoria usando invece UTF-16. I codepoint Unicode che non rientrano in un singolo char a 16 bit verranno codificati utilizzando una coppia di 2 char denominata surrogata.

Se non si passa un valore di parametro a String.getBytes(), viene restituito un array di byte con il contenuto della stringa codificato utilizzando il set di caratteri predefinito del sistema operativo sottostante. Se si desidera garantire un array con codifica UTF-8, è necessario utilizzare invece getBytes ("UTF-8").

La chiamata a String.charAt() restituisce un char codificato in UTF-16 originale solo dalla memoria in memoria della stringa.

controllare questo link: java utf8 encoding - char, string types

7

Java utilizza UTF-16 (16 bit) per la rappresentazione in memoria.

Questo simbolo dell'euro si adatta a questo, anche se ha bisogno di tre byte in UTF-8.

+1

Quindi un char è sempre codificato in UTF-16? –

+2

Sì, e questo è un po 'un problema, perché Unicode è più grande di quello. Alcuni codepoint Unicode richiedono ora due caratteri in Java. Quindi il risultato di 'length' o' charAt' potrebbe non essere del tutto soddisfacente se si utilizza "l'intero catalogo". – Thilo

+0

Quindi il parametro I pass -Dfile.encoding = UTF-8 in realtà non cambia molto, possiamo dire? –