2009-03-17 15 views
56

UTF-8でjavaでエンコードされた文字列をISO-8859-1に変換しようとしています。例えば、文字列 'âabcd' 'はISO-8859-1でE2として表されています。 UTF-8では、2バイトで表されます。 C3 A2私は信じています。 getbytes(エンコーディング)を行い、ISO-8859-1エンコーディングで新しい文字列を作成すると、2つの異なる文字が取得されます。 â。キャラクターを同じように保つためにこれを行う他の方法はありますか?JavaでUTF-8をISO-8859-1に変換する方法 - シングルバイトとして保持する方法

答えて

29
byte[] iso88591Data = theString.getBytes("ISO-8859-1"); 

トリックを行います。あなたの説明から、あなたが「ISO-8859-1 Stringを格納しようとしているように思えます。 JavaのStringオブジェクトはで、常にがUTF-16で暗黙的にエンコードされます。そのエンコーディングを変更する方法はありません。

あなたができることは、上記のような.getBytes()メソッドを使用して、他のエンコーディングを構成するバイトを取得することです。

+0

がこのファイルを作成するときに、私は問題を解決する助け、ありがとう文字列を次のようにログに出力するまで: 'string = new String(string.getBytes(" UTF-16 "));' 'Log.d(TAG、string);' –

+0

「JavaのStringオブジェクトは常に暗黙のうちにUTF-16でエンコードされる」ということをおねがいします。これは私が持っていた問題を解決したもので、gエナジーに知っておくと便利です! –

92

あなたはUTF-16以外の文字エンコーディングを扱っている場合は、java.lang.Stringまたはプリミティブcharを使用すべきではない - あなただけbyte[]配列やByteBufferオブジェクトを使用する必要があります。その後、あなたはエンコーディング間の変換にjava.nio.charset.Charsetを使用することができます。

Charset utf8charset = Charset.forName("UTF-8"); 
Charset iso88591charset = Charset.forName("ISO-8859-1"); 

ByteBuffer inputBuffer = ByteBuffer.wrap(new byte[]{(byte)0xC3, (byte)0xA2}); 

// decode UTF-8 
CharBuffer data = utf8charset.decode(inputBuffer); 

// encode ISO-8559-1 
ByteBuffer outputBuffer = iso88591charset.encode(data); 
byte[] outputData = outputBuffer.array(); 
+0

ありがとうございました..本当に有益 - Luckylak –

+4

はい、本当に良い発言です。 Javaでは、String自体がUTF-16でエンコードされます。常に。ストリングが他のものにコード化されていると考えるのは意味がありません。代わりに、いくつかのエンコーディングでテキストを表す生データ(バイト)があります。次に、(エンコーディングを使用して)文字列を(UTF-16で)デコードするか、またはStringからバイトにデコードします。アップアップされました! –

+0

@Adam Rosenfield:Byte [] ==> byte [] – AndrewBourgeois

7

をUTF-8には、そのデータから文字列を作成し、使用して文字列をエンコードするバイトのセットから始めて、その後、いくつかのバイトが異なる中で文字列をコード取得エンコーディング:

byte[] utf8bytes = { (byte)0xc3, (byte)0xa2, 0x61, 0x62, 0x63, 0x64 }; 
    Charset utf8charset = Charset.forName("UTF-8"); 
    Charset iso88591charset = Charset.forName("ISO-8859-1"); 

    String string = new String (utf8bytes, utf8charset); 

    System.out.println(string); 

    // "When I do a getbytes(encoding) and " 
    byte[] iso88591bytes = string.getBytes(iso88591charset); 

    for (byte b : iso88591bytes) 
     System.out.printf("%02x ", b); 

    System.out.println(); 

    // "then create a new string with the bytes in ISO-8859-1 encoding" 
    String string2 = new String (iso88591bytes, iso88591charset); 

    // "I get a two different chars" 
    System.out.println(string2); 

この出力文字列と正しくISO88591バイト:

âabcd 
e2 61 62 63 64 
âabcd 

だからあなたのバイト配列が正しいencodとペアにされませんでしたINGの:

String failString = new String (utf8bytes, iso88591charset); 

    System.out.println(failString); 

出力

âabcd 

(どちらかという、またはあなただけのファイルにUTF8バイトを書き、ISO88591として他の場所でそれらを読んで)

-3

追い出し非ISO-8859-1文字を、 '?'で置き換えられます。 (例でISO-8859-1 DBに送信する前):

utf8String = new String(utf8String.getBytes()、 "ISO-8859-1");

+4

ASCII以外の文字を '? 'に置き換えると、文字列を失うことなく文字列を変換することが可能になると、恐ろしい解決策のように思えます。 – s4y

0

文字列に正しいエンコーディングがある場合は、別のエンコーディングのバイト数を取得するために多くの処理を行う必要はありません。

public static void main(String[] args) throws Exception { 
    printBytes("â"); 
    System.out.println(
      new String(new byte[] { (byte) 0xE2 }, "ISO-8859-1")); 
    System.out.println(
      new String(new byte[] { (byte) 0xC3, (byte) 0xA2 }, "UTF-8")); 
} 

private static void printBytes(String str) { 
    System.out.println("Bytes in " + str + " with ISO-8859-1"); 
    for (byte b : str.getBytes(StandardCharsets.ISO_8859_1)) { 
     System.out.printf("%3X", b); 
    } 
    System.out.println(); 
    System.out.println("Bytes in " + str + " with UTF-8"); 
    for (byte b : str.getBytes(StandardCharsets.UTF_8)) { 
     System.out.printf("%3X", b); 
    } 
    System.out.println(); 
} 

出力:アダムローゼンフィールドの答えに加えてエンコードするファイルの場合

Bytes in â with ISO-8859-1 
E2 
Bytes in â with UTF-8 
C3 A2 
â 
â 
0

...

public class FRomUtf8ToIso { 
     static File input = new File("C:/Users/admin/Desktop/pippo.txt"); 
     static File output = new File("C:/Users/admin/Desktop/ciccio.txt"); 


    public static void main(String[] args) throws IOException { 

     BufferedReader br = null; 

     FileWriter fileWriter = new FileWriter(output); 
     try { 

      String sCurrentLine; 

      br = new BufferedReader(new FileReader(input)); 

      int i= 0; 
      while ((sCurrentLine = br.readLine()) != null) { 
       byte[] isoB = encode(sCurrentLine.getBytes()); 
       fileWriter.write(new String(isoB, Charset.forName("ISO-8859-15"))); 
       fileWriter.write("\n"); 
       System.out.println(i++); 
      } 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       fileWriter.flush(); 
       fileWriter.close(); 
       if (br != null)br.close(); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } 

    } 


    static byte[] encode(byte[] arr){ 
     Charset utf8charset = Charset.forName("UTF-8"); 
     Charset iso88591charset = Charset.forName("ISO-8859-15"); 

     ByteBuffer inputBuffer = ByteBuffer.wrap(arr); 

     // decode UTF-8 
     CharBuffer data = utf8charset.decode(inputBuffer); 

     // encode ISO-8559-1 
     ByteBuffer outputBuffer = iso88591charset.encode(data); 
     byte[] outputData = outputBuffer.array(); 

     return outputData; 
    } 

} 
0

、私は、ByteBuffer.array()はバッファの基本となるバイト配列を返すことを追加したいと思います最後の文字まで必ずしも「トリム」されているわけではありません。this答えに記載されているような余分な操作が必要です。特に:

byte[] b = new byte[bb.remaining()] 
bb.get(b); 
1

これは私が必要なものです:私のファイル名の文字列は、私が気づかない可能性が改行文字を含んでいた:

public static byte[] encode(byte[] arr, String fromCharsetName) { 
    return encode(arr, Charset.forName(fromCharsetName), Charset.forName("UTF-8")); 
} 

public static byte[] encode(byte[] arr, String fromCharsetName, String targetCharsetName) { 
    return encode(arr, Charset.forName(fromCharsetName), Charset.forName(targetCharsetName)); 
} 

public static byte[] encode(byte[] arr, Charset sourceCharset, Charset targetCharset) { 

    ByteBuffer inputBuffer = ByteBuffer.wrap(arr); 

    CharBuffer data = sourceCharset.decode(inputBuffer); 

    ByteBuffer outputBuffer = targetCharset.encode(data); 
    byte[] outputData = outputBuffer.array(); 

    return outputData; 
} 
関連する問題