2

以下のコードを実行していますが、Windows と Unix のどちらを使用しているかによって、"some_string".getBytes() から異なる結果が得られます。この問題はどの文字列でも発生します (非常に単純な ABC と同じ問題を試しました。

コンソールに出力された以下の違いを参照してください。

以下のコードは、Java 7 を使用して十分にテストされています。完全にコピーすると、実行されます。

さらに、下の 2 つの画像で 16 進数の違いを確認してください。最初の 2 つの画像は、Windows で作成されたファイルを示しています。ANSI と EBCDIC でそれぞれ 16 進数値を確認できます。3 番目の黒い画像は Unix のものです。16 進数 (-c オプション) と、EBCDIC であると思われる読み取り可能な文字を確認できます。

ですから、私の率直な質問は次のとおりです。どちらの場合も Java 7 を使用しているだけなので、なぜそのようなコードが異なる動作をするのでしょうか? どこかで特定のプロパティを確認する必要がありますか? おそらく、Windows の Java は特定のデフォルト形式を取得し、Unix では別の形式を取得します。その場合、どのプロパティを確認または設定する必要がありますか?

ここに画像の説明を入力

Unix コンソール:

$ ./java -cp /usr/test.jar test.mainframe.read.test.TestGetBytes
H = 76 - L
< wasn't found

Windows コンソール:

H = 60 - <
H1 = 69 - E
H2 = 79 - O
H3 = 77 - M
H4 = 62 - >
End of Message found

コード全体:

package test.mainframe.read.test;

import java.util.ArrayList;

public class TestGetBytes {

       public static void main(String[] args) {
              try {
                     ArrayList ipmMessage = new ArrayList();
                     ipmMessage.add(newLine());

                     //Windows Path
                     writeMessage("C:/temp/test_bytes.ipm", ipmMessage);
                     reformatFile("C:/temp/test_bytes.ipm");
                     //Unix Path
                     //writeMessage("/usr/temp/test_bytes.ipm", ipmMessage);
                     //reformatFile("/usr/temp/test_bytes.ipm");
              } catch (Exception e) {

                     System.out.println(e.getMessage());
              }
       }

       public static byte[] newLine() {
              return "<EOM>".getBytes();
       }

       public static void writeMessage(String fileName, ArrayList ipmMessage)
                     throws java.io.FileNotFoundException, java.io.IOException {

              java.io.DataOutputStream dos = new java.io.DataOutputStream(
                           new java.io.FileOutputStream(fileName, true));
              for (int i = 0; i < ipmMessage.size(); i++) {
                     try {
                           int[] intValues = (int[]) ipmMessage.get(i);
                           for (int j = 0; j < intValues.length; j++) {
                                  dos.write(intValues[j]);
                           }
                     } catch (ClassCastException e) {
                           byte[] byteValues = (byte[]) ipmMessage.get(i);
                           dos.write(byteValues);
                     }
              }
              dos.flush();
              dos.close();

       }

       // reformat to U1014
       public static void reformatFile(String filename)
                     throws java.io.FileNotFoundException, java.io.IOException {
              java.io.FileInputStream fis = new java.io.FileInputStream(filename);
              java.io.DataInputStream br = new java.io.DataInputStream(fis);

              int h = br.read();
              System.out.println("H = " + h + " - " + (char)h);

              if ((char) h == '<') {// Check for <EOM>

                     int h1 = br.read();
                     System.out.println("H1 = " + h1 + " - " + (char)h1);
                     int h2 = br.read();
                     System.out.println("H2 = " + h2 + " - " + (char)h2);
                     int h3 = br.read();
                     System.out.println("H3 = " + h3 + " - " + (char)h3);
                     int h4 = br.read();
                     System.out.println("H4 = " + h4 + " - " + (char)h4);
                     if ((char) h1 == 'E' && (char) h2 == 'O' && (char) h3 == 'M'
                                  && (char) h4 == '>') {
                           System.out.println("End of Message found");
                     }
                     else{
                           System.out.println("EOM not found but < was found");
                     }
              }
              else{
                     System.out.println("< wasn't found");
              }
       }
}
4

1 に答える 1

3

を呼び出すときに文字セットを指定していないgetBytes()ため、基盤となるプラットフォーム (または Java の起動時に指定されている場合は Java 自体) のデフォルトの文字セットが使用されます。これはStringドキュメントに記載されています:

パブリックバイト[] getBytes()

プラットフォームのデフォルトの charset を使用して、この String を一連のバイトにエンコードし、結果を新しいバイト配列に格納します。

getBytes()コードで文字セットを指定できるオーバーロードされたバージョンがあります。

public byte[] getBytes(Charset charset)

指定されたcharset を使用してこの String を一連のバイトにエンコードし、結果を新しいバイト配列に格納します。

于 2016-04-20T01:12:01.470 に答える