序列化(转)

前言: 当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为对象。 把对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为对象的过程称为对象的反序列化。
这里还要注意对象的序列化主要有两种用途:1) 在网络上传送对象的字节序列。2) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中。
.net为我们主要提供了三种序列化方式:

它们的主要区别请参考下图:

最后来三段代码,简单实现常用的序列化和反序列化。
1、使用BinaryFormatter


using System;
using System.Data;
using System.Configuration;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace BinarySerialize
{
    
//要使一个类可序列化,最简单的方法是使用Serializable 属性对它进行标记
    [Serializable]
    
public class User //要序列化的用户类
    {
        
public int tid = 252;
        
public string name = "jeff wong";
        [NonSerialized]
        
public string sex = "male"// 性别被标识为不可序列化
    }
    
public class SerializeUtil
    {
       
private static string strFile = "c:\\User.data";

        
public static void Serialize(User testUser)
        {  

            //可以用MemoryStream等
            
using (FileStream fs = new FileStream(strFile, FileMode.Create))
            {
                BinaryFormatter formatter 
= new BinaryFormatter();
                formatter.Serialize(fs, testUser);
            }
        }

        
public static User DeSerialize()
        {
            User testUser 
= null;
            
using (FileStream fs = new FileStream(strFile, FileMode.Open))
            {
                BinaryFormatter formatter 
= new BinaryFormatter();
                testUser 
= (User)formatter.Deserialize(fs);
            }
            
return testUser;
        }
    }

    
public class Program
    {
        
static void Main()
        {
            SerializeUtil.Serialize(
new User());//序列化
            User tmpUser = SerializeUtil.DeSerialize();//反序列化
            Console.WriteLine(tmpUser.tid + "-" + tmpUser.name);
            Console.WriteLine(tmpUser.sex); 
//sex被标识为不可序列化,所以总为null
            Console.ReadLine();
        }
    }
}

2、使用SoapFormatter
 先添加System.Runtime.Serialization.Formatters.Soap引用,然后和BinaryFormatter类似,我们只需要做一下简单修改即可:
 a.将using语句中的.Formatter.Binary改为.Formatter.Soap;
 b.将所有的BinaryFormatter替换为SoapFormatter.
 c.确保报存文件的扩展名为.xml
 经过上面简单改动,即可实现SoapFormatter的串行化,这时候产生的文件就是一个xml格式的文件。


using System;
using System.Data;
using System.Configuration;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;

namespace SoapSerialize
{
    
//要使一个类可序列化,最简单的方法是使用Serializable 属性对它进行标记
    [Serializable]
    
public class User //要序列化的用户类
    {
        
public int tid = 252;
        
public string name = "jeff wong";
        [NonSerialized]
        
public string sex = "male"// 性别被标识为不可序列化
    }
    
public class SerializeUtil
    {
       
private static string strFile = "c:\\User.xml"//存为xml

        
public static void Serialize(User testUser)
        {
            
using (FileStream fs = new FileStream(strFile, FileMode.Create))
            {
                SoapFormatter formatter 
= new SoapFormatter();
                formatter.Serialize(fs, testUser);
            }
        }

        
public static User DeSerialize()
        {
            User testUser 
= null;
            
using (FileStream fs = new FileStream(strFile, FileMode.Open))
            {
                SoapFormatter formatter 
= new SoapFormatter();
                testUser 
= (User)formatter.Deserialize(fs);
            }
            
return testUser;
        }
    }

    
public class Program
    {
        
static void Main()
        {
            SerializeUtil.Serialize(
new User());//序列化
            User tmpUser = SerializeUtil.DeSerialize();//反序列化
            Console.WriteLine(tmpUser.tid + "-" + tmpUser.name);
            Console.WriteLine(tmpUser.sex); 
//sex被标识为不可序列化,所以总为null
            Console.ReadLine();
        }
    }
}

(3)、使用XmlSerializer
想使用XmlSeralizer进行串行化我们需要做一下修改:
 a.添加System.Xml.Serialization命名空间.
 b.Serializable和NoSerialized属性将被忽略,而是使用XmlIgnore属性,它的行为与NoSerialized类似.
 c.XmlSeralizer要求类有个默认的构造器.


using System;
using System.Data;
using System.Configuration;
using System.IO;
using System.Xml.Serialization;

namespace XmllSerialize
{
    [Serializable]
    
public class User //要序列化的用户类
    {
        
public int tid = 252;
        
public string name;
        [XmlIgnore]
        
public string sex = "male"
       
        
public User(string name)
        {
            
this.name = name;
        }
        
/// <summary>
        
/// 必须注意:XmlSeralizer要求类有个默认的构造器
        
/// </summary>
        public User()
        { 
        }
    }
    
public class SerializeUtil
    {
       
private static string strFile = "c:\\User.xml"//存为xml

        
public static void Serialize(User testUser)
        {
            XmlSerializer xs 
= new XmlSerializer(typeof(User));
            
using (Stream stream = new FileStream(strFile, FileMode.Create, FileAccess.Write, FileShare.Read))
            {
                xs.Serialize(stream, testUser);
            }
        }

        
public static User DeSerialize()
        {
            User testUser 
= null;
            
using (FileStream fs = new FileStream(strFile, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                XmlSerializer xs 
= new XmlSerializer(typeof(User));
                testUser 
= (User)xs.Deserialize(fs);
            }

            
return testUser;
        }
    }

    
public class Program
    {
        
static void Main()
        {
            SerializeUtil.Serialize(
new User("jeff wong"));//序列化
            User tmpUser = SerializeUtil.DeSerialize();//反序列化
            Console.WriteLine(tmpUser.tid + "-" + tmpUser.name);
            Console.WriteLine(tmpUser.sex);
            Console.ReadLine();
        }
    }
}
posted @ 2009-07-02 17:10  西门啥都吹  阅读(376)  评论(0编辑  收藏  举报