0

Java を使用するフォーマットを合理的に作成した dat ファイルに (ある種の) ログを書き込むプログラムからバイナリ ファイルを読み込もうとしています。私はそれを次のようにロードしています:

DataInputStream in = new DataInputStream(new FileInputStream("file.dat"));

System.out.println("Bytes skipped: " + in.skipBytes(4));

System.out.println(in.readLong());

問題は、readLong() の値が予想と異なることです。Hex Workshop では、16 進ブロックを強調表示します。

BF02 0000

そして、それが有効な符号付きの短い/長い数値であると報告しますが、出力は私が期待しているものとは大きく異なります。Java ドキュメントを見ると、64 ビット (8 バイト) の long をクラス化すると記載されていますが、他のソースでは符号付き long 整数は 32 ビットである必要があることが示されています。これを回避する方法はありますか?

乾杯、

トム

4

4 に答える 4

3

プリミティブ型は、異なる言語や異なるプラットフォームでは異なるものを意味します。(たとえば、C では、aa long が一部のプラットフォームでは 32 ビットであり、他のプラットフォームでは 64 ビットであることは珍しくありません。

最初に、.dat ファイルのタイプとバイト オーダー (ビッグ/リトル エンディアン) を知る必要があります。次に、個々のバイトを適切な Java 型にアセンブルします。.dat ファイルが 32 ビットの符号付き整数を指定する場合、Java の int が適しています。符号なしの 32 ビット整数の場合、Java には符号なしの型がないため、Java で long を使用してすべての可能な値を取得する必要があります。

ファイル内の整数がリトル エンディアンの場合は、次のように読み取ります。

 int i = (in.readByte()) | (in.readByte() << 8) | (in.readByte() << 16) | (in.readByte() << 24)

ビッグエンディアンの場合は、

int i = (in.readByte() << 24) | (in.readByte() << 16) | (in.readByte() << 8) | (in.readByte())

(私は atm を覚えていません。Java のプロモーション ルールはここにあります。ビット シフトの前に int を生成するために &0xff を使用する必要があるかもしれません) もちろん、バイト配列を読み込んで、呼び出す代わりにその配列を操作できます必要に応じて個別に in.readByte() 。

于 2009-07-08T16:43:54.533 に答える
2

Java の long は常に8 バイト (64 ビット) です。言語やプラットフォームが異なれば、使用する用語も異なります。4 バイトを読み取りたい場合は、int を読み取ります。

于 2009-07-08T16:20:38.577 に答える
1

データを読み取るときに ByteBuffer を使用し、 order() メソッドでバイト オーダーを変更できます。

于 2009-07-12T08:28:22.467 に答える
0

Preonを使用する場合、すべてのシフトとマスキングを行う必要はありません。エンコードされたデータ構造を反映するクラスでは、いくつかのフィールドをバインドされた数値としてマークするだけで、ほとんどすべてです。

class EncodedDataStructure {

  @BoundNumber
  private long theLong;

}

4 バイトのみを読み取りたいが、それでも long にしたい場合:

@BoundNumber(size="32") // Size is number of bits
private long theLong;

Or if you want to force it to be big or little endian:

@BoundNumber(size="32", byteOrder=Endian.Big)
private long theLong;

...そして、あなたはそれを次のように読みます:

Codec<EncodedDataStructure> codec = Codecs.create(EncodedDataStructure.class);
EncodedDataStructure structure = Codecs.decode(codec, file);
于 2009-07-12T07:09:27.600 に答える