Perché è & # 191; visualizzato diverso in Windows vs Linux anche quando si utilizza UTF-8?

StackOverflow https://stackoverflow.com/questions/176196

  •  05-07-2019
  •  | 
  •  

Domanda

Perché quanto segue è diverso in Linux vs Windows?

System.out.println(new String("¿".getBytes("UTF-8"), "UTF-8"));

in Windows:

¿

in Linux:

¿

È stato utile?

Soluzione

System.out.println () restituisce il testo nella codifica predefinita del sistema, ma la console interpreta tale output in base alla propria impostazione di codifica (o "codepage"). Sul tuo computer Windows le due codifiche sembrano corrispondere, ma sulla scatola di Linux l'output è apparentemente in UTF-8 mentre la console lo sta decodificando come codifica a byte singolo come ISO-8859-1. O forse, come ha suggerito Jon, il file sorgente viene salvato come UTF-8 e javac lo sta leggendo come qualcos'altro, un problema che può essere evitato usando le escape Unicode.

Quando devi produrre qualcosa di diverso dal testo ASCII, la soluzione migliore è scriverlo su un file usando una codifica appropriata, quindi leggere il file con un editor di testo - le console sono troppo limitate e troppo dipendenti dal sistema. A proposito, questo bit di codice:

new String("¿".getBytes("UTF-8"), "UTF-8")

... non ha alcun effetto sull'output. Tutto ciò che fa è codificare il contenuto della stringa in un array di byte e decodificarlo di nuovo, riproducendo la stringa originale, un costoso no-op. Se vuoi produrre testo in una particolare codifica, devi usare un OutputStreamWriter, in questo modo:

FileOutputStream fos = new FileOutputStream("out.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");

Altri suggerimenti

Non sono sicuro di dove sia esattamente il problema, ma vale la pena notare che

¿ (0xc2,0xbf)

è il risultato della codifica con UTF-8

0xbf,

che è il punto di codice Unicode per ¿

Quindi, come nel caso di Linux, l'output non viene visualizzato come utf-8, ma come una stringa a byte singolo

Controlla che codifica ha il tuo terminale Linux.

Per gnome-terminal in ubuntu - vai su " Terminale " menu e seleziona " Imposta codifica caratteri " ;.

Per mastice, Configurazione - > Finestra - > Traduzione - > UTF-8 (e se non funziona, vedi questo post ).

Esegui questo codice per determinare se si tratta di un problema del compilatore o della console:

public static void main(String[] args) throws Exception {
    String s = "¿";
    printHex(Charset.defaultCharset(), s);

    Charset utf8 = Charset.forName("UTF-8");
    printHex(utf8, s);
}

public static void printHex(Charset encoding, String s)
        throws UnsupportedEncodingException {
    System.out.print(encoding + "\t" + s + "\t");

    byte[] barr = s.getBytes(encoding);
    for (int i = 0; i < barr.length; i++) {
        int n = barr[i] & 0xFF;
        String hex = Integer.toHexString(n);
        if (hex.length() == 1) {
            System.out.print('0');
        }
        System.out.print(hex);
    }
    System.out.println();
}

Se i byte codificati per UTF-8 sono diversi su ciascuna piattaforma (dovrebbe essere c2bf ), si tratta di un problema del compilatore.

Se si tratta di un problema con il compilatore, sostituisci " & # 191; " con " \ u00bf " .

È difficile sapere esattamente quali byte contiene il codice sorgente o la stringa su cui viene richiamato getBytes (), a causa delle codifiche dell'editor e del compilatore.

Riesci a produrre un programma breve ma completo contenente solo ASCII (e il relativo escape \ uxxxx nella stringa) che mostra ancora il problema?

Sospetto che il problema potrebbe essere dovuto all'output della console su Windows o Linux, ma sarebbe bene ottenere prima un programma riproducibile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top