首页 > 代码库 > 二进制序列化与反序列化。Net理论篇上(一)
二进制序列化与反序列化。Net理论篇上(一)
对于从事底层信息通信的同行而言,序列化及反序列化想必都是耳熟能详的。脱离很多书面的标准概念,就个人理解而言,序列化和反序列化的本质其实为了找到一种公共的通用的数据格式达到一个无界的境界,正如方言对于普通话,各国语言对于英语。而我们需要做的是去发现这么一种具体的格式,并且完成一个相对对称的特性,如同压缩跟解压缩。
常规的序列化和反序列化的格式通常有如下几种:binary,JSON, XML和SOAP等。 当然有其他的,这个只能恕我孤陋寡闻了。通常我们会选取短小精悍的JSON 和更具通用的XML,当然很多同行也会采用SOAP。我也多会采用JSON,毕竟Newtonsoft.JSON的强悍还是不言而喻的,(对于阿里的fastjson,我只能深表同情,哥知道不是你们的错,这是后话)。唯独不常见binary的身影,让我深感诧异,也许是我阅历不深,特此反省。不过,很多通信底层例如socket亦或之上的TCP或者UDP,都才用binary作为通信的基础格式,不否认可以借助其他的方式去取得binary的数据。但是如有更加通用直接的binary序列化和反序列化类库或者架包不是显得更好。所以下定决心做一个自己的binary序列化和反序列化的类库,当然出于工作的需要,对于代码现在不方便贴出来,出于职业的操守,所以暂时深感抱歉。先跟各位分享下自己的架设和期间遇到的问题,当然有合适的时间,我还是希望这个能成为开源的一部分,也是我希望接下去要做的事。
在之前,我必须得承认这个并不具有原创性,很多设计原理的灵感来源于同类软件的设计,毕竟站在巨人肩上才能看得更远。所以之前,我会拿Newtonsoft.JSON举例,也是我目前用得相对比较多的软件,当然这个近似万能的类库也有很多自己的限制,例如对其中不支持byte[]的序列化和反序列化就深感奇怪,不知道这是出于怎样的心理和考虑,大概是觉得很多人会把string再转成byte带来的重复转化的愧疚,这也成为我想做自己的binary序列化类库的其中的一个出发点。当然,还是先看看它是怎么做得。
JsonConvert是Newtonsoft.JSON的入口,通过源码分析,你确实会发现在这个如同生态园的入口之后是个多么丰富的世界,当你领略完之后你在回头看这个入口,你会再次发现这个入口确实恰如其分,妙到豪颠。也许略有夸张,在我看来这个一个经典的门面模式的应用,而这个应用确实非常有用。
还是先看看它是怎么工作的。首先当我们使用JsonConvert. SerializeObject(object)时,它首先创建临时的StringBuilder的临时数据池,其目的我不在累诉。并且同时构建一个数据写入器JsonWriter负责对转化后的字符串片段的有序写入,这里强调有序写入,因为这个很讲究,这也是Newtonsoft.JSON没有采用并发读写其中一个相对重要的原因,当然更重要的可能是并发读写的不可控。在做完准备工作之后,它需要对object进行描述就如同文件描述一样,生成相应的JsonContract 以方便去控制后续的编码转化行为。真正完成各种类型转化的是编码转化层。根据JsonContract,Newtonsoft.JSON能够识别需要用何种JsonConverter去处理。当找到具体的JsonConverter时候就可以借助它将目标转化为string通过JsonWriter写入到数据池中。对于反序列化亦然,只是过程逆转而已。
这里需要抓住几个关键点以及难点,首先如何定义JasnContract,这个类在我看来是整个类库的核心部件,看似无关紧要,但实际却是举足轻重,因为真正的调度其实是由它做出的。 第二需要找到各种基本类型对应转化到通用类型的途径,第三点就是找到自定义类型转化的方式方法。
下一张应该是为具体自定义二进制序列化和反序列化的设计。