快速业务通道

关于系列化和反序列化的一个问题

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-05-20

一、情景重现

昨天在做数据库同步测试的时候,用到了一点序列化和反序列化的技术。我把某个表的字段抽象成一 个实体类DiagramInfo,然后把客户端新增的记录用一个泛型集合存储,再把这个泛型集合系列化,通过 TCP发送到服务端,服务端对其进行反序列化,再把这些数据写入数据库。这大概就是这个操作的流程。

序列化我用的是System.Runtime.Serialization.Iformatter类,把泛型集合序列化成二进制流。序列 化的部分代码如下:

       private void Seriable(List<DiagramInfo> diagrams)
       {

            MemoryStream stream = new MemoryStream();

            IFormatter formater = new BinaryFormatter();

            formater.Serialize(stream, diagrams);

            stream.Flush();

            serializedData = stream.ToArray();

            stream.Close();

        }

然后使用TCP协议发送,这部分内容省略。

服务端部分接收数据,并保存成MemoryStream,然后对其反序列化,部分代码如下:

do
{

      bytesRead = stream.Read(responseBuffer, 0, bufferSize);

      memstream.Write(responseBuffer, 0, bytesRead);

}

while (bytesRead > 0);

IFormatter formater = new BinaryFormatter();

diagrams = (List<DiagramInfo>)formater.Deserialize(memstream);

stream.Close();

memstream.Close();

client.Close();

这时运行客户端和服务端,进行数据同步,结果出现了如下的错误信息:

错误行为:diagrams = (List<DiagramInfo>)formater.Deserialize(memstream);

按字面意思是:在转换完成前遇到了流结束。

二、解决方案

经过google搜索,对于这个错误有人回答了以下几种错误可能:

1.序列化和反序列化时类型不同,这里可以排除;

2.在序列化时没有清空流的缓冲区,及没有使用Flush()方法,这里也可以排除;

3.反序列化前的接收过程缓冲区大小可能不够,对于这条我觉得应该没问题才对,反序列化是在获取 流之后进行的,跟缓冲区大小应该没关系,个人意见,也没试过;

4.在反序列化前加上strem.Position=0。(stream是待反序列化的流,实指memstream)

经过测试,第四种可能适用于我的程序。那么为什么会这样呢,经过单步调试,观察 memstream.Postion的值变化,发现每对其进行一次写操作,该值都会指向末尾,这就解释了为什么程序 会报这样的错误了。但是我搞不懂的是为什么反序列化函数(Deserialize)不是默认对整个流进行反序 列化,而是从Positon的位置开始呢?

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号