【问题标题】:Read structured data from binary file -?从二进制文件中读取结构化数据-?
【发布时间】:2010-07-14 14:22:45
【问题描述】:

我知道文件结构,假设这个结构是这样的:

[3-bytes long int],[1-byte long unsigned integer],[4-bytes long unsigned integer]

因此该文件包含此类记录的链。

在 Java 中解析此类文件最优雅的方法是什么?

假设我们可以定义一个全长的 byte[] 数组并用 InputStream 读取它,但是如何将其子元素转换为正确的整数值呢?

首先,java中的字节值是有符号的,在我们的例子中我们需要无符号值。 接下来,是否有有用的方法可以将字节子数组(例如,从第 1 个字节到第 4 个字节)转换为正确的整数值?

我肯定知道,Perl 中有函数 pack 和 unpack,允许您将字节字符串表示为表达式,假设“VV”表示 2 个无符号长整数值。您定义这样一个字符串并将其作为参数提供给 packunpack 函数,以及要打包/解包的字节。 Java / Apache libs等中有这样的东西吗?

【问题讨论】:

标签: java parsing file-io


【解决方案1】:

类似于@Bryan Kyle 的示例,但更短。我喜欢更短,但这并不意味着更清晰,你决定。 ;) 注意:readByte() 是有符号的,如果没有用 0xFF 屏蔽会产生意想不到的结果。

DataInputStream dis = ... 

// assuming BIG_ENDIAN format
int a = dis.read() << 16 | dis.read() << 8 | dis.read(); 
short b = (short) dis.read(); 
long c = dis.readInt() & 0xFFFFFFFFL; 

ByteBuffer bb = 
bb.position(a_random_postion);
int a = (bb.get() & 0xFF) << 16 | (bb.get() & 0xFF) << 8 | (bb.get() & 0xFF); 
short b = (short) (bb.get() & 0xFF); 
long c = bb.readInt() & 0xFFFFFFFFL; 

【讨论】:

    【解决方案2】:

    您可以查看这个基于DataInputStream 类的示例BinaryReader 类。

    【讨论】:

      【解决方案3】:

      您应该可以使用DataInputStream 执行此操作。自从我做了很多这样的开发以来已经有一段时间了,但我似乎记得的技巧是,如果您的输入格式和语言的数据类型之间存在阻抗不匹配,您将需要逐字节构造数据.在这种情况下,您似乎需要这样做,因为数据结构具有奇怪的大小结构。

      为了给你一个例子来读取第一条记录,你可能需要做这样的事情(我使用 a、b 和 c 作为记录的属性)

      DataInputStream dis = ...
      
      int a = 0;
      a = dis.readByte();
      a = a << 8;         
      a = a | dis.readByte();
      a = a << 8;
      a = a | dis.readByte();
      
      short b = 0;
      b = dis.readByte();
      
      long c = 0;
      c = dis.readByte();
      c = c << 8;
      c = c | dis.readByte();
      c = c << 8;
      c = c | dis.readByte();
      c = c << 8;
      c = c | dis.readByte();
      

      很明显,这段代码可以通过复合一些语句来收紧,但你明白了一般的想法。您可能会注意到,对于正在读取的每个属性,我必须使用一个大于所需的原语,因此不会出现任何溢出错误。供参考,在 Java 中:

      • 字节 = 1 个字节
      • short = 16 位,2 个字节
      • int = 32 位,4 个字节
      • long = 64 位,8 字节

      【讨论】:

        猜你喜欢
        • 2020-05-06
        • 1970-01-01
        • 1970-01-01
        • 2011-05-08
        • 1970-01-01
        • 2011-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多