九天雁翎的博客
如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。 -- Paul Graham

序列化支持(2)—Boost的序列化库


序列化支持(2)—Boost的序列化库

write by 九天雁翎(JTianLing) -- www.jtianling.com

讨论新闻组及文件

这里找到了一些序列化的库,MFC的序列化库不能在Linux下用,剩下可以尝试的还有s11nCommonC++,和boost的序列化库了。。。特别要提到的就是boost的库。。。。一个序列化的库也写了230K,真是服了。。。。基本上我在公司写的序列化类也就一个文件一个类,也就1K,包括了所有的基本结构。。。很显然,boost的野心是很大的。。。出于对准标准库的尊敬。。。自然优先boost。特别要提到的是,Boost有所有我需要的东西-_-!并且我发现BoostASIO库就是我以前计划完成的目标。。。。。以后有特别有文章详细提到。。。

 

这里感谢为Boost库进行中文文档性工作的哥们,实在是感谢,虽然我常常以学英文为由去参看原文文档,甚至还阅读过基本原著,但是在文中引用的时候插入一篇的英文似乎是不太合适的,并且当我需要很快知道答案的时候,中文能够让我更快的处理,感谢你们。

以下引号中内容摘自Boost中文文档1.37.0版本:

这里有个对序列化比较正统的解释

“这里,我们用术语 "serialization序列化" 来表示将任意一组C++数据结构解构为一串字节的、可逆的过程。这样的系统可用于在另一个程序上下文中重新构建一个等价的结构。根据不同的上下文,它可以用来实现对象持久化、远程参数传递或其它功能。在本系统中,我们使用术语 "archive存档" 来指代这个字节流的特定表现。它可以是一个二进制数据文件、文本文件、XML或其它由本库的用户所创建的东西。”

注意,序列化的作用如我之前所述有:实现对象持久化、远程参数传递

 

我们对于这个系统的目标是:

  1. 代码的可移植性 - 只依赖于 ANSI C++ 所提供的功能。
  2. 代码的经济性 - 使用C++的一些特性,如 RTTI, 模板, 和多重继承等等,以使得代码更短也更易于使用。
  3. 各个类定义版本的无关性。即当一个类的定义更改时,旧文件仍可导入到新版本的类中。
  4. 深的指针保存和恢复。即指针的保存与恢复分别保存和恢复所指的数据。
  5. 对共享数据指针的正确恢复。
  6. STL容器及其它常用模板的序列化。
  7. 数据的可移植性 - 在一个平台上创建的字节流可以在另一平台上读出。
  8. 类的序列化与存档格式的正交性。即任何文件格式都可用于保存任意一组C++数据结构的序列化信息而无需调整。
  9. 非介入性。可以对不作更改的类进行序列化。即不要求进行序列化的类派生自某个特定基类或者实现特定的成员函数。这一点对于要将序列化应用于某些我们不能或不愿修改的类库中的类来说是十分必要的。
  10. archive 的接口必须足够简单,以易于创建一种新的存档类型。
  11. archive 的接口又必须足够丰富,才可以创建出象XML这样风格的存档。

野心够大,其描述的第17点很符合我的需要,第6点是属于额外的好处。

我们公司的序列化方式是,对于已实现序列化的结构使用其结构的Serialize方法,对于基本结构使用序列化类的Serialize,因为序列化类已经重载了基本结构的的Serialize实现。我曾经对比过这种方法和MFC的序列化方式,还有stream的使用方式,我感觉假如都使用stream那样重载<<,>>操作符的方式是最能节省击键数的,并且也足够的形象,并且个人认为,在某种程序上来说,stringstream就可以做一个简单的Archive实现来用。但是这里有一个比较不方便的就是,都需要先判断是存储还是读取,然后分别调用操作符,这里就相当于多了一倍的工作量,而公司的方式(统一到Serialize函数),虽然多了函数名的输入,但是对于输入还是输出可以不关心,这是其很大的优势。当时一下子还分不清孰优孰劣,但是出于亲近C++ 流实现的方式。碰到Boost的重载&操作符方式一下子傻了。。。。呵呵,听了太多的教条,太多的教导告诉我们不要重载操作符进行莫名奇妙的操作,除了真正用到其操作符原始涵义的时候,我还真从来没有去重载过他们,这里算是见识到了,虽然是重载了与操作符进行序列化运算,有点扭曲,但是,一切是简单就好,下面的示例你可以看到,这样兼有我上面所述的两种方案的优点。

       回想起工作当中用了多少CTRL-C,CTRL-Vyy,p)去实现该死的一行又一行的序列化啊,在我们公司吓死人的物品扩展属性中,有60个以上的字段。。。-_-!也记不清多少次添加成员变量却忘写序列化函数导致的bug,虽然这样的bug都都容易找,但是都出在与同事联合调试的时候,还是浪费了很多时间。Boost的这种方案仅仅也是简化了实现,并没有办法根除这一点,还是必须说明。虽然其提供了不介入的方式来完成序列化,但是本质上序列化函数还是需要自己来写,以后要是有种方式能够为用户新添的任何结构或类进行序列化,而不需要用户进行额外的工作时,那才是完美的序列化方案。。。。毕竟,越少的工作,出错的机会也就越少。

       现在想起来,重复工作最多的几个地方在哪?其一,结构的拷贝构造函数和=操作符的重载,为了安全,公司都是一个字段一个字段的写,累死人,也容易错。其二,就是一个字段一个字段的写序列化了。其三,目前还没有解决办法,数据库的操作,无论是MySQLC API还是ODBC,都是有多少个字段(呵呵,多少个“?”)就得bind多少个结构的数据。。。。也是累死人。。。想想我的两个记日志工作就心寒(其一就是日志服务器,另外还有监控中心对整个服务器运行情况的日志记录),那个重复工作的啊。。。。还好有vim:)以前还特意讲过怎么用vim来简化我的工作,没有vim我都吐血了。最好用的就是q的记录功能和ctrl+a的联合使用了(可惜Viemu不支持ctrl+a

       本来来说,Boost的文档属于开源库中最最详细的一列了,基本上跟着文档走就都能学会了,但是对于初学者来说可能有的地方太过简略,当然,对于熟悉boost的人来说那叫主题吐出,一针见血。我这里主要摘文档中的例子来讲讲,偶尔发表一下自己的见解,有的地方也跟进实现去看看。毕竟原有的例子仅仅是很简单的。这里自然还是推荐任何学习者都像我一样,调试其中的每一个例子,而不仅仅是看看而已。

 

write by 九天雁翎(JTianLing) -- www.jtianling.com

 

分类:  网络技术 
标签:  Boost 

Posted By 九天雁翎 at 九天雁翎的博客 on 2009年03月19日

前一篇: windows/linux服务器程序支持库的开发(2)--序列化支持(1) 后一篇: 序列化支持(3)—Boost的序列化库的使用