2009-03-16 9 views
56

Qualcuno sa come convertire una stringa da ISO-8859-1 a UTF-8 e di nuovo in Java?Come posso convertire tra ISO-8859-1 e UTF-8 in Java?

Sto ottenendo una stringa dal Web e salvandola in RMS (J2ME), ma voglio conservare i caratteri speciali e ottenere la stringa dal RMS ma con la codifica ISO-8859-1. Come faccio a fare questo?

+0

possibile duplicato di [Codifica conversione in java] (http: // StackOverflow.it/questions/229015/encoding-conversion-in-java) – kamaci

risposta

87

In generale, non è possibile farlo. UTF-8 è in grado di codificare qualsiasi punto di codice Unicode. ISO-8859-1 può gestire solo una piccola parte di essi. Quindi, la transcodifica da ISO-8859-1 a UTF-8 non è un problema. Andando all'indietro da UTF-8 a ISO-8859-1, i caratteri "sostitutivi" (& # xFFFD;) appariranno nel testo quando vengono trovati caratteri non supportati.

per la transcodifica di testo:

byte[] latin1 = ... 
byte[] utf8 = new String(latin1, "ISO-8859-1").getBytes("UTF-8"); 

o

byte[] utf8 = ... 
byte[] latin1 = new String(utf8, "UTF-8").getBytes("ISO-8859-1"); 

è possibile esercitare un maggiore controllo utilizzando il livello inferiore Charset API. Ad esempio, puoi sollevare un'eccezione quando viene trovato un personaggio non codificabile o utilizzare un carattere diverso per il testo sostitutivo.

+1

Per ulteriori informazioni sulla codifica dei caratteri e sul motivo per cui non ha molto senso passare da UTF-8 a ISO-8859 (o ASCII o ANSI per quella materia), vedere questa spiegazione: http://www.joelonsoftware.com /articles/Unicode.html –

+0

Ecco un buon riassunto da tale link: 'Ci sono centinaia di codifiche tradizionali che possono solo memorizzare alcuni punti di codice correttamente e modificare tutti gli altri punti di codice in punti interrogativi. Alcune codifiche popolari del testo inglese sono Windows-1252 (lo standard Windows 9x per le lingue dell'Europa occidentale) e ISO-8859-1, ovvero Latin-1 (utile anche per qualsiasi lingua dell'Europa occidentale). Ma prova a memorizzare lettere russe o ebraiche [o caratteri speciali] in queste codifiche e ottieni un sacco di punti interrogativi. UTF 7, 8, 16 e 32 hanno tutti la bella proprietà di essere in grado di memorizzare correttamente qualsiasi punto di codice. –

+0

Vale la pena ricordare che Windows-1252 (Windows Latin 1) estende ISO-8859-1 (ufficiale latino 1) compilando alcuni dei caratteri "Controllo Unicode" 0x80 - 0xbf. Anche i browser su Mac e Linux lo rispettano. Quindi in alcuni punti usa invece Windows-1252. –

6

Se si dispone di un String, si può fare:

String s = "test"; 
try { 
    s.getBytes("UTF-8"); 
} catch(UnsupportedEncodingException uee) { 
    uee.printStackTrace(); 
} 

Se avete un 'rotto' String, hai fatto qualcosa di sbagliato, la conversione di un String ad un String in un'altra codifica non è defenetely la strada andare! È possibile convertire un String in un byte[] e viceversa (data una codifica). In Java String s sono codificati AFAIK con UTF-16 ma questo è un dettaglio di implementazione.

Diciamo che avete un InputStream, si può leggere in un byte[] e poi convertire che ad un String utilizzando

byte[] bs = ...; 
String s; 
try { 
    s = new String(bs, encoding); 
} catch(UnsupportedEncodingException uee) { 
    uee.printStackTrace(); 
} 

o meglio ancora (grazie a Erickson) usa InputStreamReader così:

InputStreamReader isr; 
try { 
    isr = new InputStreamReader(inputStream, encoding); 
} catch(UnsupportedEncodingException uee) { 
    uee.printStackTrace(); 
} 
+1

Se si dispone di un InputStream, è necessario includerlo con un InputStreamReader. – erickson

3

Ecco un modo semplice con uscita String (ho creato un metodo per fare questo):

public static String (String input){ 
    String output = ""; 
    try { 
     /* From ISO-8859-1 to UTF-8 */ 
     output = new String(input.getBytes("ISO-8859-1"), "UTF-8"); 
     /* From UTF-8 to ISO-8859-1 */ 
     output = new String(input.getBytes("UTF-8"), "ISO-8859-1"); 
    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } 
    return output; 
} 
// Example 
input = "Música"; 
output = "Música"; 
4

che ha funzionato per me: ("Uzum bağları" è la corretta scritto in turco)

Convert ISO-8859-1 a UTF-8:

String encodedWithISO88591 = "üzüm baÄları"; 
String decodedToUTF8 = new String(encodedWithISO88591.getBytes("ISO-8859-1"), "UTF-8"); 
//Result, decodedToUTF8 --> "üzüm bağları" 

Convert UTF-8 a ISO-8859-1

String encodedWithUTF8 = "üzüm bağları"; 
String decodedToISO88591 = new String(encodedWithUTF8.getBytes("UTF-8"), "ISO-8859-1"); 
//Result, decodedToISO88591 --> "üzüm baÄları" 
+0

Cosa accadrebbe se scriveste il seguente codice: 'String a = new String (encodedWithUTF8.getBytes (" ISO88591 ")," ISO-8859-1 ")' e 'String b = new String (encodedWithUTF8.getBytes (" ISO88591 ")," UTF-8 ")'? Se la stringa è in una codifica e otteniamo byte usando l'altro, cosa succede sotto il cofano? – parsecer

+0

Puoi provarli e vedere i risultati sul tuo IDE, e se segui questo URL http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#String (byte [] ,% 20java.nio.charset.Charset) vedrai la definizione del metodo. Non conosco i dettagli esatti del processo. – webmaster

+1

Se qualcuno ha bisogno di questo - penso che i comandi di cui sopra farebbero quanto segue: 'a' prenderebbe i byte di' UTF-8', convertirli in 'ISO' byte e quindi usare una tabella' bytes-> chars' di ' Codifica ISO' per stampare la stringa. In caso di stringa 'b' userebbe una tabella' bytes-> chars' di 'UTF-8', quindi mappando essenzialmente' ISO' byte secondo le regole di 'UTF'. 'a' verrà stampato OK anche se è' ISO', perché Java non rovina la sua memorizzazione interna di byte. 'b' potrebbe essere danneggiato perché alcuni dei caratteri di' ISO' verranno stampati come se appartenessero alla codifica 'UTF'. – parsecer

0

Apache Commons IO Charsets class può tornare utile:

String utf8String = new String(org.apache.commons.io.Charsets.ISO_8859_1.encode(latinString).array())