0

我正在尝试从将日志(各种)写入 dat 文件的程序中读取二进制文件,我已经很好地确定了使用 Java 的格式。我正在加载它:

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

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

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

问题是 readLong() 的值与我期望的不同,在 Hex Workshop 我突出显示了十六进制块

BF02 0000

并报告它是一个有效的签名短/长数字 - 但是输出与我的预期非常不同。查看Java Docs,它声明它的类长为64位(8字节),而其他来源显示有符号长整数应该是32位 - 有没有办法解决这个问题?

干杯,

汤姆

4

4 回答 4

3

原始类型在不同的语言和不同的平台中意味着不同的东西。(例如,在 C 语言中,aa long 在某些平台上为 32 位而在其他平台上为 64 位的情况并不少见。

首先,您必须知道 .dat 文件中的类型以及字节顺序(大/小端)。然后将各个字节组装成适当的 java 类型。如果 .dat 文件指定 32 位有符号整数,则 java 中的 int 将是合适的。如果它是一个无符号的 32 位整数,您可能需要在 java 中使用 long 来捕获所有可能的值,因为 java 没有无符号类型。

如果文件中的整数是 little endian,则按如下方式读取:

 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 中的提升规则,你可能需要和它们 &0xff 在位移之前产生一个 int )当然,你可以读入一个字节数组并对该数组进行操作而不是调用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 个字节,但仍希望它很长:

@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 回答