在这一刻,我手工解析.有人知道有助于进行这种解析的库吗?
编辑:“手工”意味着我将数据字节By Byte排序到正确的Order并将其转换为Int / Byte等.还有一些数据是无符号的.
解决方法
sbinary的主要优点是它为您提供了一种将每个对象的线格式描述为Format对象的方式.然后,您可以将这些格式化的类型封装在更高级别的Format对象中,Scala只要将其作为隐式对象包含在当前作用域中,就可以重新查找该类型.
如下所述,我现在建议人们使用scodec而不是sbinary.作为如何使用scodec的例子,我将实现如何读取以下C struct的内存中的二进制表示形式:
struct ST { long long ll; // @ 0 int i; // @ 8 short s; // @ 12 char ch1; // @ 14 char ch2; // @ 15 } ST;
匹配的Scala案例类将是:
case class ST(ll: Long,i: Int,s: Short,ch1: String,ch2: String)
我正在使自己的事情变得容易一些,只是说我们正在存储Strings而不是Chars,我会说它们在结构体中是UTF-8字符.我也没有处理这个架构的endian细节或long和int类型的实际大小,只是假设它们分别是64和32.
Scodec解析器通常使用组合器来构建较低级解析器.所以在下面我们来定义一个解析器,它结合了一个8字节的值,一个4字节的值,一个2字节的值,一个1字节的值和一个1个字节的值.这种组合的返回是一个元组编解码器:
val myCodec: Codec[Long ~ Int ~ Short ~ String ~ String] = int64 ~ int32 ~ short16 ~ fixedSizeBits(8L,utf8) ~ fixedSizeBits(8L,utf8)
然后,我们可以通过调用它的xmap函数将其转换成ST case类,它需要两个函数,一个将Tuple编解码器转换为目标类型,另一个函数将其转换为Tuple表单:
val stCodec: Codec[ST] = myCodec.xmap[ST]({case ll ~ i ~ s ~ ch1 ~ ch2 => ST(ll,i,s,ch1,ch2)},st => st.ll ~ st.i ~ st.s ~ st.ch1 ~ st.ch2)
现在,您可以使用这样的编解码器:
stCodec.encode(ST(1L,2,3.shortValue,"H","I")) res0: scodec.Attempt[scodec.bits.BitVector] = Successful(BitVector(128 bits,0x00000000000000010000000200034849)) res0.flatMap(stCodec.decode) => res1: scodec.Attempt[scodec.DecodeResult[ST]] = Successful(DecodeResult(ST(1,3,H,I),BitVector(empty)))
我会鼓励你看Scaladocs而不是在指南,因为Scaladocs有更多的细节.该指南是非常基础的一个很好的开始,但它没有进入组合部分,但是Scaladocs涵盖的很好.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。