1

「windows1255」でエンコードされた文字列があります。「UTF-8」に変換できる安全な方法はありますか

文字列とその逆?

一般に、変換する安全な方法(データが破損しないことを意味する)はありますか

Javaでのエンコーディング?

     str.getBytes("UTF-8");
     new String(str,"UTF-8");

元の文字列が「UTF-8」でエンコードされていない場合、データが破損する可能性はありますか?

4

2 に答える 2

2

StringJava でオブジェクトを UTF-16 以外として適切にエンコードすることはできません。仕様で定義されているオブジェクトの唯一のエンコーディングであるためです。もちろん、1252 個の値を char[] に入れ、そこから文字列を作成するなど、不都合なことを行うこともできますが、すぐに問題が発生します。

あなたが持つことができるのは、さまざまな方法でエンコードされた byte[] であり、Charset を受け取るコンストラクターを使用してgetBytes、コード内のように String との間で変換できます。

したがって、文字列を中間として使用して変換を行うことができます。JDK で直接変換を行う方法については知りませんが、実際には中間体はあまりコストがかからない可能性があります。

ラウンドトリップ変換について - 通常、データを失うことなくエンコーディング間で変換できるとは限りません。Unicode 文字の全範囲を処理できるエンコーディングはごくわずかです (UTF ファミリ、GB18030 など)。一方、多くのレガシー文字セットは小さなサブセットのみをエンコードします。入力が表現可能なセットに該当することが確実でない限り、データを失うことなくこれらの文字セットを安全に往復することはできません。

于 2013-02-03T11:12:01.573 に答える
1

文字列は一連の抽象的な文字になろうとしていますが、ユーザーの観点からはエンコードされていません。もちろん、内部エンコーディングが必要ですが、それは実装の詳細です。

String を UTF-8 としてエンコードし、結果を UTF-8 としてデコードすることは意味がありません。次の点でノーオペレーションになります。

(new String(str.getBytes("UTF-8"), "UTF-8") ).equals(str) == true;

しかし、文字列の抽象化がうまくいかず、上記が「不可逆」な変換になる場合があります。内部実装の詳細のため、文字列には、UTF-8 (または内部 UTF-16 エンコーディング*を含む、その件に関する任意のエンコーディング) で表すことができないペアになっていない UTF-16 サロゲートを含めることができます。したがって、それらはエンコーディングで失われ、デコードして戻すと、無効なペアになっていないサロゲートのない元の文字列が得られます。

あなたの質問から私が得ることができる唯一のことは、バイナリ データを Windows-1255 として解釈した結果、文字列の結果が得られたということです。これは、UTF-8 で解釈されるべきでした。これを修正するには、このソースにアクセスして、明示的に UTF-8 デコードを使用する必要があります。

ただし、誤った解釈による文字列しか得られない場合は、Windows-1255 では非常に多くのバイトが表現されておらず、文字列にならないため、実際には何もできません。

そうでない場合は、次の方法で元の意図したメッセージを完全に復元できます。

new String( str.getBytes("Windows-1255"), "UTF-8");

* 有効な UTF-16 ではないため、対になっていないサロゲートが最初に文字列に存在することを許可するのは、Java では実際には間違っています。

于 2013-02-03T14:11:21.993 に答える