2010-02-10 15 views
6

Utilizzo di Java 6 per ottenere caratteri a 8 bit da una stringa:String.getBytes ("ISO-8859-1") mi dà 16 bit caratteri su OS X

System.out.println(Arrays.toString("öä".getBytes("ISO-8859-1"))); 

mi dà, su Linux: [-10, 28] ma OS XI ottiene: [63, 63, 63, -89]

Mi sembra di ottenere lo stesso risultato quando utilizzo la nuova classe di nio CharSetEncoder. Che cosa sto facendo di sbagliato? O è colpa di Apple? :)

risposta

4

sono riuscito a riprodurre questo problema salvando il file di origine come UTF-8, poi dire il compilatore è stato davvero MacRoman:

javac -encoding MacRoman Test.java

avrei pensato javac stabilizzerebbe in UTF-8 su OSX, ma forse no. O forse stai usando un IDE e è predefinito su MacRoman. In ogni caso, devi usare UTF-8.

+0

Sembra che MacRoman sia la codifica predefinita sul mio sistema OSX. Il file sorgente con questo valore letterale è codificato in UTF-8 e lo analizza erroneamente come MacRoman. Quindi come risolvere questo? Specificare la codifica UTF-8 non sembra una buona opzione. Cosa succede se ho dei buoni vecchi file ISO-8859-1? – lennartcl

+0

Se alcuni dei tuoi file sono ISO-8859-1, dovrai comunque compilarli separatamente e specificare * che * la codifica. Ti suggerisco di specificare sempre UTF-8, sia per il salvataggio che per la compilazione. Se un file MacRoman o ISO-8859-1 si insinua, lo saprai quando la compilazione fallisce; è molto più difficile ingannare UTF-8 nell'accettare dati falsi piuttosto che nella maggior parte delle altre codifiche. –

+0

Ho pensato che sarebbe passato a ISO-8859-1 se non fosse in grado di leggere un file come UTF-8. Ma questo non sembra essere il caso sulla mia macchina Linux. Quindi '-encoding utf-8' dà lo stesso comportamento. Non mi sento ancora del tutto a mio agio nell'usare questo interruttore, ma mi rendo conto che dovrò aggiustarlo sulla mia scatola OSX e sistemi simili. Non posso fare a meno di chiedermi se non esiste una "correzione" globale, quindi il mio sistema non esploderà la prossima volta che mi imbatterò in un progetto che utilizza letterali stringa UTF-8 e non ho un test unitario per prendere il problema? – lennartcl

1

Forse il set di caratteri per la sorgente non è impostato (e quindi diverso in base alle impostazioni locali del sistema)?

È possibile eseguire la stessa classe compilata su entrambi i sistemi (non ricompilare)?

+0

Questo è sicuramente il caso. Quel codice, compilato correttamente, produrrà lo stesso output su tutte le piattaforme supportate. –

2

Qual è la codifica del file sorgente? 63 è il codice per ? che significa "il carattere non può essere convertito nella codifica specificata".

Quindi la mia ipotesi è che hai copiato il file sorgente sul Mac e che il file sorgente utilizza una codifica che il compilatore Java non si aspetta. IIRC, OS X si aspetta che il file sia UTF-8.

0

Ricordare che esiste più di un modo per rappresentare i caratteri. Mac OS X utilizza unicode per impostazione predefinita, quindi la stringa letterale potrebbe non essere rappresentata da due byte. È necessario assicurarsi di caricare la stringa dal set di caratteri in arrivo appropriato; per esempio, specificando nel sorgente un carattere di escape \ u.

+0

Per quello che vale, un personaggio accentato può essere rappresentato in due modi; come singolo glifo (ö) o come carattere di combinazione (\ u0308 o). – AlBlue

+0

Bene, in questo caso il codice Java viene generato codice. Cambiare il modo in cui questi caratteri sono codificati nel letterale non è fattibile. – lennartcl

2

Il file sorgente sta producendo "öä" combinando i caratteri.

Guardate questa:

System.out.println(Arrays.toString("\u00F6\u00E4".getBytes("ISO-8859-1"))) 

Questa è la stampa [-10, -28] come ci si aspetta (non mi piace per la stampa in questo modo, ma io so che non è il punto della questione) , perché sono specificati i codepoint Unicode, scolpiti nella pietra, e il tuo editor di testo non è autorizzato a "giocare in modo intelligente" combinando "o" e "a" con segni diacritici.

In genere, quando si verificano questi problemi probabilmente desidera utilizzare due OS X Un * x Commmands di capire cosa sta succedendo sotto il cofano: file e hexdump sono molto convenienti in questi casi.

Si desidera eseguirli sul file di origine e si consiglia di eseguirli sul file di classe.

+0

Utili piccoli strumenti. Quindi, come mai javac non sa che questo è un file UTF-8? – lennartcl