尝试从二进制文件中读取非Java原语

时间:2009-07-08 16:16:45

标签: java binary load

我正在尝试从一个程序读取一个二进制文件,该程序将一个日志(各种类型)写入一个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 个答案:

答案 0 :(得分:3)

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

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

如果文件中的整数是小端,请按如下方式读取:

 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中的促销规则,你可能需要和&amp; 0xff一起在位移之前产生一个int) 当然,您可以读取一个字节数组并对该数组进行操作,而不是单独调用in.readByte()。

答案 1 :(得分:2)

Java中的长总是 8个字节(64位)。不同的语言和平台使用不同的术语。如果要读取4个字节,请读取int。

答案 2 :(得分:1)

您可以在读取数据时使用ByteBuffer并使用order()方法更改字节顺序。

答案 3 :(得分: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);