.NET 中的序列化

    序列化(serialization)就是把对象的当前状态(字段及其值)转换数据流,可以把得到的数据流存放到文件、数据库、内存或其它地方;然后在我们需要时,使用反序列化(deserialization)将对象恢复。在.Net中,要序列化一个对象,可以使用属性将类的元素标为可序列化的(Serializable)和不可被序列化的(NonSerialized)。通过SoapFormatter(基于XML)和BinaryFormatter可以得到不同的数据流格式。

一、可序列化(Serializable)和不可序列化(NonSerialized)属性
    如果允许一个类序列化,需要在类上标记[Serializeble]属性

None.gif [Serializable]  // 通过标记该属性,说明此类可以被序列化
None.gif
public   class  User
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private int id;
InBlock.gif    
private string name;
InBlock.gif    [NonSerialized] 
//标记该属性后,email字段将不会被序列化
InBlock.gif
    private string email;
InBlock.gif
InBlock.gif    
public User(int id, string name, string email)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
this.id = id;
InBlock.gif        
this.name = name;
InBlock.gif        
this.email = email;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

    如果一个可序列化的类包含了对另一个类的引用,那么被引用的类也必须支持序列化

None.gif [Serializable]  // 通过标记该属性,说明此类可以被序列化
None.gif
public   class  User
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private int id;
InBlock.gif    
private string name;
InBlock.gif    
private Contact contact; //引用了一个类
InBlock.gif

InBlock.gif    
public User(int id, string name, string email)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
this.id = id;
InBlock.gif        
this.name = name;
InBlock.gif        
this.email = email;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif[Serializable]
None.gif
public   class  Contact
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif  
private string email;
InBlock.gif  
private string qq;
InBlock.gif  
private string msn
ExpandedBlockEnd.gif}

 

 二、SoapFormatter和BinaryFormatter
    下面的代码分别使用SoapFormatter和BinaryFormatter将User类序列化到文件中:

None.gif namespace  SerializApp
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
using System;
InBlock.gif    
using System.Collections.Generic;
InBlock.gif    
using System.Text;
InBlock.gif    
using System.IO;
InBlock.gif    
using System.Runtime.Serialization;
InBlock.gif    
using System.Runtime.Serialization.Formatters.Soap;
InBlock.gif    
using System.Runtime.Serialization.Formatters.Binary;
InBlock.gif
InBlock.gif    
class Program
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            User user 
= new User(1001"netflu""netflu@msn.com");
InBlock.gif
InBlock.gif            FileStream mySoap 
= File.Create(@"C:\Soap_user.txt");
InBlock.gif            
new SoapFormatter().Serialize(mySoap, user);
InBlock.gif            mySoap.Close();
InBlock.gif
InBlock.gif            FileStream myBinary 
= File.Create(@"C:\Binary_user.dat");
InBlock.gif            
new BinaryFormatter().Serialize(myBinary, user);
InBlock.gif            myBinary.Close();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    [Serializable]
InBlock.gif    
public class User
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private int id;
InBlock.gif        
private string name;
InBlock.gif        [NonSerialized]
InBlock.gif        
private string email;
InBlock.gif
InBlock.gif        
public User(int id, string name, string email)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.id = id;
InBlock.gif            
this.name = name;
InBlock.gif            
this.email = email;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

使用SoapFormatter得到的数据流(Soap_user.txt):

None.gif < SOAP-ENV:Envelope  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd ="http://www.w3.org/2001/XMLSchema"  xmlns:SOAP-ENC ="http://schemas.xmlsoap.org/soap/encoding/"  xmlns:SOAP-ENV ="http://schemas.xmlsoap.org/soap/envelope/"  xmlns:clr ="http://schemas.microsoft.com/soap/encoding/clr/1.0"  SOAP-ENV:encodingStyle ="http://schemas.xmlsoap.org/soap/encoding/" >
None.gif
< SOAP-ENV:Body >
None.gif
< a1:User  id ="ref-1"  xmlns:a1 ="http://schemas.microsoft.com/clr/nsassem/SerializApp/SerializApp%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull" >
None.gif
< id > 1001 </ id >
None.gif
< name  id ="ref-3" > netflu </ name >
None.gif
</ a1:User >
None.gif
</ SOAP-ENV:Body >
None.gif
</ SOAP-ENV:Envelope >

使用BinaryFormatter得到的数据流(Binary_user.dat):

None.gif                BSerializApp ,  Version = 1.0.0.0 ,  Culture = neutral ,  PublicKeyToken = null   SerializApp.User   idname    ?     netflu

通过对SoapFormatter和BinaryFormatter输出的数据流进行观察,可以发现他们各有优缺点,Soap的可读性高,而Binary的数据量小。


三、自定义序列化
    如果要精确控制对象的序列化,需要实现ISerializable接口

None.gif // ISerializable接口原型
None.gif
public   interface  ISerializable
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
ExpandedBlockEnd.gif    }

    以下是一个实现了ISerializable接口的类:

None.gif     [Serializable]
None.gif    
public   class  User : ISerializable
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
private int id;
InBlock.gif        
private string name;
InBlock.gif        
private string email;
InBlock.gif
InBlock.gif        
public User(int id, string name, string email)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.id = id;
InBlock.gif            
this.name = name;
InBlock.gif            
this.email = email;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private User(SerializationInfo info, StreamingContext context)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.id = info.GetInt32("id");
InBlock.gif            
this.name = info.GetString("name");
InBlock.gif            
this.email = info.GetString("email");
ExpandedSubBlockEnd.gif        }

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
ISerializable 成员#region ISerializable 成员
InBlock.gif
InBlock.gif        
public void GetObjectData(SerializationInfo info, StreamingContext context)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            info.AddValue(
"id", id);
InBlock.gif            info.AddValue(
"name", name);
InBlock.gif            info.AddValue(
"email", email);
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif        
#endregion

ExpandedBlockEnd.gif    }

主要通过SerializationInfo对象提供的AddValue方法通过键值对来保存一个值,然后通过一系列GetValue方法来取出值。




 

转载于:https://www.cnblogs.com/netflu/archive/2006/02/28/339962.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值