Winform NETWORK:关于序列化

最近在做SOCKET,也就顺便看了看序列化。。。挺好用的,编码起来也方便多,但是传递的报文变长了许多,在这里总结一下

序列化和反序列化可以方便地实现对象(Object)和字节数组(byte[])的转换,其中序列化实现将Object转换为byte[],反序列化将byte[]转换为Object。
这是某网友贴出来的,谢谢。。。。

        /// <summary>  
        /// 序列化  
        /// </summary>  
        /// <param name="data">要序列化的对象</param>  
        /// <returns>数据缓冲区</returns>  
        public static byte[] Serialize(object obj)
        {
         BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            formatter.Serialize(stream, obj);
            byte[] data = stream.GetBuffer();
            return data;
        }
        /// <summary>  
        /// 反序列化  
        /// </summary>  
        /// <param name="data">数据缓冲区</param>  
        /// <returns>对象</returns>  
        public static object Deserialize(byte[] data)
        {

           BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

            System.IO.MemoryStream stream = new System.IO.MemoryStream(data);
            data = null;
            Object obj = formatter.Deserialize(stream);
            return obj;
        }

比如登陆信息,一个USER的对象则可通过这样的序列化封装起来,加在报文里发送至远端服务器

CLASS USER
{
STRING USERNAME;
STRING PASSWORD;
}
然后在服务器把分析接收到的报文后,取其序列化的字段,反序列化一下成对象,则可方便地操作了

而如果在以前,我们是可能是封装这样一条报文
PC端发送登录信息(功能号:0x00 0x00)
字段名称                数据类型及长度      说明
Account_Length       1 Byte                        用户登录名长度
Account Byte        [Account_Length]        用户登录名
Password_Length   1 Byte                用户密码长度
Password  Byte     [Password_Length]      用户密码

封包在这里就不详谈了。。。。。。。

服务器再根据相应的报文解析,而本人觉得原先的方式在数据的传递上是很完美的,因为通讯协议在开发中改变并不多,如果大了大不了重新订一条得了,而序列化,可能是为了OO吧,挺方便的,但是传递的东西得多好多,特别是走SOAP时。

在这里还希望达人指点一下,但序列化的确也是种好办法吧!特别是还有持久化这么一个作用。。。。

在牛人xingd博客里有记载着:

BinaryFormatter用于ASP.NET中的ViewState保存和恢复,以及Remoting中TcpChannel的默

认 Formatter,SoapFormatter用于Remoting中HttpChannel的默认Formatter,而XmlSerializer 用于.NET中的Web Service。

虽然SoapFormatter产生的也是XML格式的字符流,但其中包含了Soap协议所需要的一些数

据,因此比 XmlSerializer产生的数据量要大,这也是Web Service比使用HttpChannel+SoapFormatter的Remoting效率要好的原因。

Remoting,Web Service了解不多,在这不好说啥,但BinaryFormatter也的确是三种方式

里最节省的,个人觉得最强的吧,除非你要跨平台。。。。。


备注几下:


NET序列化是基于对象的,所以只有实例字段被序列化,静态字段不在序列化之中。。

为了标志不可序列化成员,可以使用[NoSerialized],NET反射时会先查看是否有该属性,

有则跳过
[NonSerialized]
public int _NoPubSer = 1;

反序列化时,会自动把这个值给设置成默认值,但我们可以实现IDeserializationCallback接口,在。NET反序列化之后,IDeserializationCallback唯一

的方法会被调用,允许它完成需要的自定义初始化步骤。

//完成自定义初始化工作

 public void OnDeserialization(object sender)

 {
  //sender默认为null

  _NoPubSerString = "yTest";
 }

比如SQLCONNECTIONS这类不可序列化成员,则要通过此方法重新新建一个

有文档写着: 委托定义都被编译成可序列化对象。。。不明白是什么意义,但对于委托事件来说,没成功过,必须定义
[FIELD:NONSERIALIZED]

序列化事件

 [OnDeserialized]
 void streamOnDeserialized(StreamingContext context)
 {

    Console.WriteLine("OnDeserialized");

 }


 [OnDeserializing]
  void streamOnDeserializeing(StreamingContext context)
  {
   Console.WriteLine("OnDeserializeing");
  }

 [OnSerialized]
  void streamOnSerialized(StreamingContext context)
 {
  Console.WriteLine("OnSerialized");
  }


 [OnSerializing]
  void streamOnSerializeing(StreamingContext context)
 {
  Console.WriteLine("OnSerializeing");
}
主要有这么四个,一看名字也就知道做什么了

还有是可以多个对象序列化一起的,主要分析得看

http://www.cnblogs.com/xingd/archive/2005/02/04/101669.html

在这里就先写这么些吧,序列化还有一些高级的,比如泛型,搞不大懂,望指点。。。

谢谢












posted @ 2008-12-07 20:03  yellowyu  阅读(524)  评论(0编辑  收藏  举报