2011-05-30 9 views
6

このコードにはどのような問題がありますか?私はISO8859 Stringを作った。だからÄÖÜのほとんどはいくつかのkrypooutputです。それはいいです。しかし、それらを元の文字(UTF8など)に変換する方法はありますか?ISO8859文字列をUTF8に変換しますか? ÄÖÜ=>ÃÃ?なぜですか?

String s = new String("Üü?öäABC".getBytes(), "ISO-8859-15"); 

    System.out.println(s); 
    //ÃÃŒ?öÀABC => ok(?) 
    System.out.println(new String(s.getBytes(), "ISO-8859-15")); 
    //ÃÂÃÅ?öÃâ¬ABC => ok(?) 
    System.out.println(new String(s.getBytes(), "UTF-8")); 
    //ÃÃŒ?öÀABC => huh? 
+0

"krypooutput"は暗号関数の出力を意味すると仮定して、なぜそれを "通常の文字"に変換しようとしていますか?それはデータの損失を招くため、安全ではありません。人間が読める形式のデータが必要な場合は、16進エンコードまたはURLエンコードを使用します。 –

+1

Javaには "ISO8859 String"のようなものはありません。 http://balusc.blogspot.com/2009/05/unicode-how-to-get-characters-right.html – axtavt

+0

を参照してください。次に、 "ÃÃŒ?öÀABC"のような入力文字列を通常に変換する方法はありますか? (文字列がISO8859ファイルのものであることが分かっている場合)。 – Lissy

答えて

4
String s = new String("Üü?öäABC".getBytes(), "ISO-8859-15"); //bug 

すべてこのコードはありませんが破損したデータです。それは、UTF-16データをシステムエンコーディング(それが何であれ)にトランスコードし、そのバイトを受け取り、それらが有効なISO-8859-15であると偽り、それらをUTF-16にトランスコードします。

次に、 "ÃÃŒ?öÀABC"のような入力文字列を通常に変換する方法はありますか? (文字列がISO8859ファイルのものであることが分かっている場合)。

次のようになります。この操作を実行するための正しい方法:Javaで

byte[] iso859_15 = { (byte) 0xc3, (byte) 0xc3, (byte) 0xbc, 0x3f, 
    (byte) 0xc3, (byte) 0xb6, (byte) 0xc3, (byte) 0xa4, 0x41, 0x42, 
     0x43 }; 
String utf16 = new String(iso859_15, Charset.forName("ISO-8859-15")); 

文字列は常にUTF-16です。他のすべてのエンコーディングは、byteタイプを使用して表す必要があります。

ここでSystem.outを使用して結果の文字列を出力すると、正しく表示されない可能性がありますが、これは異なるトランスコードの問題です。たとえば、Windows consoleのデフォルトエンコーディングは、システムエンコーディングと一致しません。 System.outで使用されるエンコーディングは、データを受信するデバイスのエンコーディングと一致する必要があります。 reading your source filesで、エディタで使用しているのと同じエンコーディングを使用していることを確認してください。

文字データの扱いが言語によってどのように異なるかを理解するには、thisをお読みください。

+1

バイト配列に、ISO-8859-15としてエンコードされた 'ÃÃÃŒ?öÀABC'が含まれているべきではないでしょう。これはおそらくOPが望む文字列ではありません。 ISO-8859-15としてコード化された 'Üü?ääBC'は' {0x22、(byte)0xdc、(byte)0xfc、0x3f、(byte)0xf6、(byte)0xe4、0x41、0x42、0x43、0x22} ' – McDowell

7

new String("Üü?öäABC".getBytes(), "ISO-8859-15");のような構成要素は、ほとんど常にのエラーであり、です。

あなたがここでやっているプラットフォームのデフォルトエンコーディングとISO-8859-15としてそれを再解釈がStringに戻ってそれを変換するには、対応するbyte[]を取得し、Stringオブジェクトを取っています。

プラットフォームのデフォルトのエンコーディングは、(例えば、ISO-8859-1のために、またはこの特定のStringための違いはありませんに十分に近い)ISO-8859-15であることを起こる場合、それは何もしません(つまり、実際の効果はありません)。

それ以外の場合はとなります。Stringを破壊します。

あなたは、あなたはおそらくあまりにも遅れている、Stringを「修正」しよう場合:あなたは、バイナリデータが変換される時点でそれを使用する必要があり、あなたがデータを読み取るために、特定のエンコーディングを使用する必要がある場合Stringデータ。たとえば、InputStreamから読み取る場合は、の正しいエンコードをInputStreamReaderのコンストラクタに渡す必要があります。「事後」の問題を解決しようとすると

  1. 困難を行うことになり、
  2. 頻繁にいなくても可能(間違ったエンコーディングでbyte[]をデコードすることができるので、破壊的な操作)。
1

Java文字列は、内部的には常にUTF16配列として(そして、合併後のクラスファイルにはUTF8として)格納されるため、文字列をバイト配列のように解釈することはできません。特定のエンコーディングの文字列からバイト配列を作成する場合は、まず次のエンコーディングに変換する必要があります。

byte[] b = "Üü?öäABC".getBytes("ISO-8859-15"); 

System.out.println(new String(b, "ISO-8859-15")); // will be ok 
System.out.println(new String(b, "UTF-8")); // will look garbled 
6

これはあなたの問題を解決することを望みます。

String readable = "äöüÄÖÜßáéíóúÁÉÍÓÚàèìòùÀÈÌÒÙñÑ"; 

try { 
    String unreadable = new String(readable.getBytes("UTF-8"), "ISO-8859-15"); 
    // unreadable -> äöüÃÃÃÃáéíóúÃÃÃÃÃàèìòùÃÃÃÃÃñà 
} catch (UnsupportedEncodingException e) { 
    // handle error 
} 

そして:

String unreadable = "äöüÃÃÃÃáéíóúÃÃÃÃÃàèìòùÃÃÃÃÃñÃ"; 

try { 
    String readable = new String(unreadable.getBytes("ISO-8859-15"), "UTF-8"); 
    // readable -> äöüÄÖÜßáéíóúÁÉÍÓÚàèìòùÀÈÌÒÙñÑ 
} catch (UnsupportedEncodingException e) { 
    // ... 
} 
+0

こんにちはJooce、私は同じことを試みました、それはうまく動作しているようです、このためにありがとう – Sundhar

0

私は、UTF-8にISO-8859-1から変換された文字列を検証するために、文字の拡張セットを提供したいと思います。ここで

@Test 
public void testEnc() throws UnsupportedEncodingException { 
    String isoString = "äö"; 
    String utfString = new String(isoString.getBytes("ISO-8859-1"), "utf-8"); 
    boolean validConvertion = containsSpecialCharacter(utfString); 
    assertTrue(validConvertion); 
} 

public boolean containsSpecialCharacter(String str) { 
    String[] readable = new String[] { "Ã", "Ã", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "×", "Ø", "Ù", "Ú", "Û", "Ü", "Ã", "Þ", "ß", 
      "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "ì", "í", "î", "ï", "ð", "ñ", "ò", "ó", "ô", "õ", "ö", 
      "÷", "ø", "ù", "ú", "û", "ü", "ý", "þ", "ÿ" }; 
    for (String st : readable) { 
     if (str.contains(st)) { 
      return true; 
     } 
    } 
    return false; 
} 
2

文字列の出力を持つ簡単な方法は、(私はこれを行うためのメソッドを作成した)である:

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"; 

それが動作します!! :)

関連する問題