我有一个定义良好的二进制数据,我想为它编写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;
}
3条答案
按热度按时间qvk1mo1f1#
DataInputStream以大端字节顺序读取字节,但请注意:
3288596480 = 0个编码
反转字节,得到0x04C4 = 1220
你只需要阅读小端序中的值。关于符号的问题原来是一个转移注意力的问题。
sczxawaw2#
只需将它们分别读取为
short
(2字节- Java)和int
(4字节- Java)Java代码。您不会丢失任何信息。如果以后需要输出它们,
做一个转换,这样就不会输出有符号的数字。
根据他们的名字:
File Source ID
和Header Size
我怀疑你将对它们进行任何算术运算。如果您这样做,请小心。
或者,您可以在
long
(Java中为8字节)中读取它们,并且不用担心算术运算,因为它们不会引起问题。
或者,您可以在Java中将值作为字节数组读取,
然后将它们转换为Java代码中的适当类型。
这可能是最明确和干净的解决方案。
但它需要更多的编码。
owfi6suc3#
尽管Java不支持无符号类型,但它并不妨碍我们使用它们。
你在问题中已经提到了字节顺序的问题,所以我就不再赘述了。
避免编写复杂且容易出错的二进制数据处理代码,建议大家使用第三方库FastProto来实现。
也许您已经注意到FastProto通过注解来描述二进制数据中的字段信息,非常简单高效。
如果项目能解决您的问题,请给予一颗星星,谢谢。
GitHub回购协议:https://github.com/indunet/fastproto