Java:解析无符号二进制数据

yrdbyhpb  于 2022-12-25  发布在  Java
关注(0)|答案(3)|浏览(250)

我有一个定义良好的二进制数据,我想为它编写Java API。
文件格式如下

File Signature     char[4]               4 bytes 
File Source ID     unsigned short        2 bytes
Header Size        unsigned long         4 bytes
Max                double                8 bytes

我正在使用DataInputStream来解析数据。char很容易解析,没有问题。但是unsigned无法正确解析。
我知道Java没有无符号数,我该如何转换它呢?(请以unsigned long为例)。

    • 编辑**

下面是我编写的代码:

File file = new File("lidar.las");

DataInputStream in= new DataInputStream(new FileInputStream(file));

in.skipBytes(6);

long read = (long) (in.readInt() & 0xFFFFFFFFL);

System.out.println("read " + read);

输出为
读取3288596480
我期望的数字是1220。2我不知道写这个二进制记录的代码,可能是用c写的。3我只想写一个Java版本来读出数据。

    • 已解决**

我不确定我能回答我自己的问题。哈哈
无论如何,这里是解决方案.

private static int getSignedInt( final int unsignedInt ){

    ByteBuffer bb=ByteBuffer.allocate(1024*4);

    bb.putInt(unsignedInt).flip();

    int result =bb.order(ByteOrder.LITTLE_ENDIAN).getInt();
    bb.clear();

    return  result;
}
qvk1mo1f

qvk1mo1f1#

DataInputStream以大端字节顺序读取字节,但请注意:
3288596480 = 0个编码
反转字节,得到0x04C4 = 1220
你只需要阅读小端序中的值。关于符号的问题原来是一个转移注意力的问题。

sczxawaw

sczxawaw2#

只需将它们分别读取为short(2字节- Java)和int(4字节- Java)
Java代码。您不会丢失任何信息。如果以后需要输出它们,
做一个转换,这样就不会输出有符号的数字。
根据他们的名字:File Source IDHeader Size我怀疑你
将对它们进行任何算术运算。如果您这样做,请小心。
或者,您可以在long(Java中为8字节)中读取它们,
并且不用担心算术运算,因为它们不会引起问题。
或者,您可以在Java中将值作为字节数组读取,
然后将它们转换为Java代码中的适当类型。
这可能是最明确和干净的解决方案。
但它需要更多的编码。

owfi6suc

owfi6suc3#

尽管Java不支持无符号类型,但它并不妨碍我们使用它们。

  • uint 8可以用Java短整型或整型存储;
  • uint 16可以存储在Java Integer中;
  • uint 32可以用Java Long存储;
  • uint 64可以存储在Java BigInteger中;

你在问题中已经提到了字节顺序的问题,所以我就不再赘述了。
避免编写复杂且容易出错的二进制数据处理代码,建议大家使用第三方库FastProto来实现。

public class FileInfo {
    @BinaryType(offset = 0, length = 4)
    byte[] signature;

    @UInt16Type(offset = 4)
    Integer sourceId;

    @UInt32Type(offset = 6)
    Long headerSize;

    @DoubleType(offset = 10)
    Double max;
}

byte[] binary = ... // file binary
FileInfo info = FastProto.parse(binary, FileInfo.class);

也许您已经注意到FastProto通过注解来描述二进制数据中的字段信息,非常简单高效。

如果项目能解决您的问题,请给予一颗星星,谢谢。

GitHub回购协议:https://github.com/indunet/fastproto

相关问题