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
在这里就先写这么些吧,序列化还有一些高级的,比如泛型,搞不大懂,望指点。。。
谢谢