2

jarファイルでUTF-8からISO-8859-1に変換するコードには次のものがあります.Windowsでこのjarを実行すると、1つの結果が得られ、CentOSで別の結果が得られます。誰かが理由を知っているでしょうか?

public static void main(String[] args) {

  try {

    String x = "Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »";

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

    ByteBuffer inputBuffer = ByteBuffer.wrap(x.getBytes());
    CharBuffer data = utf8charset.decode(inputBuffer);

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

    String z = new String(outputData);

    System.out.println(z);
  }
  catch(Exception e) {
    System.out.println(e.getMessage());
  }
}

Windows では、java -jar test.jar > test.txt により、Ä、ä、É、é、Ö、ö、Ü、ü、ß、«、» を含むファイルが作成されます。

しかし、CentOS では次のようになります: �?、ä、�?、é、�?、ö、�?、ü、�?、«、»

4

3 に答える 3

2

出力について考える前に、何よりもまずJavaで正しい内部表現で文字列を取得する必要があります。IEそれはそれであるべきです:

z.equals("Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »") == true

上記は出力エンコーディングの問題なしで確認できtrueますfalse

Windowsでは、すでにこれを達成しています

ByteBuffer inputBuffer = ByteBuffer.wrap(x.getBytes());
CharBuffer data = utf8charset.decode(inputBuffer);

"Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »"からに行く必要があるの"Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »"は次のとおりです。

ByteBuffer inputBuffer = ByteBuffer.wrap(x.getBytes( windows1252/*explicit windows1252 works on CentOS too*/));
CharBuffer data = utf8charset.decode(inputBuffer);

この後、ISO-8859-1 で何かを行いますが、元の文字列の文字の半分しか ISO-8859-1 で表現できないため、無駄です。後でコードを削除できますutf8charset.decode(inputBuffer)

したがって、コードは次のようになります。

String x = "Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »";

Charset windows1252 = Charset.forName("Windows-1252");
Charset utf8charset = Charset.forName("UTF-8");

byte[] bytes = x.getBytes(windows1252);
String z = new String(bytes, utf8charset);

                                //Still wondering why you didn't just have this literal to begin with
                                //Check that the strings are internally equal so you know at least that
                                //the code is working

System.out.println(z.equals( "Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »")); 
System.out.println(z);
于 2012-12-11T17:07:21.930 に答える
2

この2行

x.getBytes());

String z = new String(outputData);

プラットフォームおよびデフォルトのエンコーディング固有です。


これは、プラットフォーム固有の変換を回避することにより、Windows および Linux で期待どおりに実行されます。

String x = "Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »";

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

ByteBuffer inputBuffer = ByteBuffer.wrap(x.getBytes(utf8charset));
CharBuffer data = utf8charset.decode(inputBuffer);

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

String z = new String(outputData, iso88591charset);

System.out.println(z);

版画

Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »
于 2012-12-11T17:02:14.133 に答える
1

次の 3 つの可能性が思い浮かびます。

  • ソースコードに実際に使用しているエンコーディングは、プラットフォームによって異なる場合があります
  • コンパイラがデフォルトで予期するエンコーディングは、プラットフォームによって異なる場合があります (コマンド ラインで指定できます)。
  • 呼び出し時に使用されるプラットフォームのデフォルトのエンコーディングはx.getBytes()、プラットフォームによって異なる場合があります

のデータは実際にはString. 呼び出しの結果をUTF-8でエンコードされたデータであるx.getBytes() かのように扱っていますが、それはプラットフォームのデフォルトが何であれ...

同様に、次のように記述します。

String z = new String(outputData);

...プラットフォームのデフォルトのエンコーディングを使用しています。そうしないでください。

バイトバッファはまったく必要ありません。を使用してエンコードし、を使用text.getBytes(encoding)してデコードするだけnew String(data, encoding)です。

于 2012-12-11T17:00:30.183 に答える