java如何解析/编码二进制消息格式?
我需要在Java中解析和编码为传统的二进制消息格式。我开始使用DataOutputStream来读/写基元类型,但我遇到的问题是消息格式不能很好地与字节偏移对齐,并且包含位标志
例如,我必须处理这样的消息:
+----------+---+---+----------+---------+--------------+
+uint32 +b +b + uint32 +4bit enum+32 byte string+
+----------+---+---+----------+---------+--------------+
其中(b)是一位标志。问题是java原语类型不与字节边界对齐,因此我无法使用DataOutputStream对其进行编码,因为我可以编写的最低级别类型是字节
是否有任何标准或第三方库可用于处理任意位级别的消息格式
编辑: 感谢@Software Monkey迫使我更仔细地查看我的规范。我使用的规范实际上是在字节边界上对齐的,因此DataOutputStream是合适的。考虑到我最初的问题,我会同意@emboss提出的解决方案
编辑: 虽然这个问题的消息格式被发现在字节边界上,但我遇到了另一种适用于原始问题的消息格式。这种格式定义了一个6位字符映射,其中每个字符实际上只占用6位,而不是整个字节,因此字符串不会在字节边界上对齐。我发现了几个解决这个问题的二进制输出流。就像这个:http://introcs.cs.princeton.edu/java/stdlib/BinaryOut.java.html
# 1 楼答案
使用Java Binary Block Parser解析消息的脚本将
# 2 楼答案
在Java中,需要应用bit arithmetics(AND、OR和NOT运算符)来更改或读取字节内的单个位。算术运算符是&;,|还有~
# 3 楼答案
我听说了Preon的好消息
# 4 楼答案
Java中有一个内置的
byte
类型,您可以使用InputStream#read(byte[])读入byte[]
缓冲区,然后使用OutputStream#write(byte[], int, int)写入输出流,所以这没有问题关于你的信息——正如你正确指出的,你一次得到的最微小的信息是一个字节,因此你必须先将你的信息格式分解成8位的块:
假设您的消息位于名为data的字节[]中。我也假设没有什么结尾
uint32的长度为32位->;这是四个字节。(在Java中解析时要小心,Java整数和long是有符号的,你需要处理它。避免麻烦的一个简单方法是使用long。数据[0]填充位31-24、数据[1]23-16、数据[2]位15-8和数据[3]位7到0。所以你需要将它们适当地向左移动,并用逻辑OR将它们粘在一起:
接下来,有两个单独的位。我想你必须检查它们是“开”(1)还是“关”(0)。为此,使用位掩码并将字节与逻辑and进行比较
第一位:(二进制掩码| 1 0 0 |=128=0x80)
第二位:(二进制掩码| 0 1 0 0 0 |=64=0x40)
要合成下一个uint32,必须在基础数据的字节边界上合成字节。例如,对于第一个字节,取剩余的6位数据[4],向左移动两位(它们将是uint32的第8位到第2位),并通过向右移动6位来“添加”数据[5]的前(最高)两位(它们将取uint32的剩余1和0插槽)。“添加”在逻辑上意味着“或”:
构建uint32的过程与第一个示例中的过程相同。等等等等
# 5 楼答案
为了补充pholser的答案,我认为Preon版本应该是这样的:
。。。但实际上,通过使用Preon的支持for dealing with enumerations directly,你可以让你的生活更加轻松
为它创建一个
Codec
并使用它来解码一些数据将是这样的: