序列化 (serialization)

来源:互联网 发布:淘宝信息管理系统要求 编辑:程序博客网 时间:2024/05/22 13:14

        序列化(serialization)描述了持久化(可能还包括传输)一个对象的状态到流的过程。被持久化的数据次序包括所有以后需要用来重建(即反序列化)对象状态所必需的信息。
    序列化简单点来理解就是把内存的东西写到硬盘中。
    实现方法:IFormatter接口中的Serialize和Deserialize方法。
   
命名空间:
    using System.Runtime.Serialization;
    一般说来,在两种情况下非常需要Serialization:
   1)当我们希望能够将对象当前的状态完整地保存到存储介质中,以便我们以后能够精确地还原对象时;
   2)当我们希望将对象从一个应用程序空间(Application domain)传递到另一个应用程序空间时
Serializable属性是不能被继承的,因此,如果从被标记为[Serializable]的类派生一个类,子类也必须被标记为[Serializable],否则它不能被持久化;
   如果你不想序列化某个成员,在其前面加上属性[NonSerialized];
   如果试图序列化一个非序列化的对象,在运行时将会收到一个SerializationException(序列化异常)的提示。

 

三种对象序列化程序

 

   为了让一个对象支持.NET序列化服务,用户需要做的只是为每一个关联的类加上[Serializable]特性;
一旦将类型配置为参与.NET序列化,接下来就是选择当持久化对象图时使用哪种格式。在.NET 2.0中,有以下三种选择:
BinaryFormatter
SoapFormatter
XmlSerializer

 

BinaryFormatter

BinaryFormatter类型使用紧凑的二进制格式将对象图序列化为一个流,这个类型在System.     Runtime.Serialization.Formatters.Binary命名空间中定义,后者是mscorlib.dll的一部分。因此,为了使用二进制序列化对象,需要指定下面的C# using指令:
// 获取对mscorlib.dll中的BinaryFormatter的访问
Using System.Runtime.Serialization.Formatters.Binary;

Book.cs位于App_Code中

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

/// <summary>
///Book 的摘要说明
/// </summary>
[Serializable]
public class Book
{
 public Book()
 {
  //
  //TODO: 在此处添加构造函数逻辑
  //
 }
    [NonSerialized]
    private string name;
    private float price;
    private string author;

    public Book(string bookname, float bookprice, string bookauthor)
    {
        name = bookname;
        price = bookprice;
        author = bookauthor;
    }

    public override string ToString()
    {
        return "书名:"+name+"价格:"+price+"作者:"+author;
    }
}

Demo:BinaryFormatter.aspx

using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ////序列化
        //Book book = new Book("C#编程基础", 90, "Tom");
        //IFormatter formatter = new BinaryFormatter();
        //Stream stream = new FileStream(@"D://myfile.txt",FileMode.Create,FileAccess.Write,FileShare.None);
        //formatter.Serialize(stream,book);
        //stream.Close();

       

       //反序列化
        BinaryFormatter form = new BinaryFormatter();
        Stream filestream = new FileStream(@"D://myfile.txt", FileMode.Open, FileAccess.Read, FileShare.Read);
        //Deserialize返回值为object
        Book obj = (Book)form.Deserialize(filestream);
        filestream.Close();
        Response.Write(obj.ToString());

    }
}

 

几点注意项

     Serializable属性是不能被继承的,因此,如果从被标记为[Serializable]的类派生一个类,子类也必须被标记为[Serializable],否则它不能被持久化;
    如果你不想序列化某个成员,在其前面加上属性[NonSerialized];
    如果试图序列化一个非序列化的对象,在运行时将会收到一个SerializationException(序列化异常)的提示。

 

SoapFormatter

      SoapFormatter类型将把对象图持久化为一个SOAP消息,当希望使用HTTP协议远程分派对象时,这个方式是一个可靠的选择。如果不熟悉SOAP的规范,现在不需要在细节上花费时间。简而言之,SOAP定义了一个标准的过程,在这个过程中可以用与平台和操作系统无关的方式调用方法;
 实现方法:在二进制序列化基础上,只需将出现的每个BinaryFormatter替换为SoapFormatter就可以持久化并接收对象为一个SOAP消息。
需要引用了System.Runtime.Serialization.Formatters.Soap.dll程序集;
Demo:SoapFormatter.aspx

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;
using System.IO;

public partial class SoapFormatter : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //序列化
        Book tom = new Book("C#编程基础", 90, "Tom");
        IFormatter formatter = new SoapFormatter();
        Stream stream = new FileStream(@"D:/MyFiles.soap", FileMode.Create, FileAccess.Write, FileShare.None);
        formatter.Serialize(stream, tom);
        stream.Close();

        //反序列化
        SoapFormatter formatter1 = new SoapFormatter();
        Stream fromStream1 = new FileStream(@"D:/MyFiles.soap", FileMode.Open, FileAccess.Read, FileShare.Read);

        //Deserialize返回值为object
        Book obj = (Book)formatter.Deserialize(fromStream1);
        fromStream1.Close();
        Response.Write(obj.ToString());
    }
}

 

XmlSerializer

 

     除SOAP和二进制格式化程序外,System.Xml.dll程序集提供了第三种格式化程序:System.Xml. Serialization.XmlSerializer,与XML数据被包含在一个SOAP消息中相反,该方式可以被用来将给定对象的状态持久化为一个纯XML。
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

/// <summary>
///employee 的摘要说明
/// </summary>

[Serializable]
public class employee
{
    public employee()
    {
        //
        //TODO: 在此处添加构造函数逻辑
        //
    }

    private int _id;
    private string _firstName;
    private string _lastName;
    private string _sex;
    private DateTime _birthday = DateTime.Now;


    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }
    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value; }
    }
    public string LastName
    {
        get { return _lastName; }
        set { _lastName = value; }
    }
    public string Sex
    {
        get { return _sex; }
        set { _sex = value; }
    }
    public DateTime BirthDay
    {
        get { return _birthday; }
        set { _birthday = value; }
    }

}

 

 

employee.cs

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

/// <summary>
///employee 的摘要说明
/// </summary>

[Serializable]
public class employee
{
    public employee()
    {
        //
        //TODO: 在此处添加构造函数逻辑
        //
    }

    private int _id;
    private string _firstName;
    private string _lastName;
    private string _sex;
    private DateTime _birthday = DateTime.Now;


    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }
    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value; }
    }
    public string LastName
    {
        get { return _lastName; }
        set { _lastName = value; }
    }
    public string Sex
    {
        get { return _sex; }
        set { _sex = value; }
    }
    public DateTime BirthDay
    {
        get { return _birthday; }
        set { _birthday = value; }
    }

}

Demo:XMLFormatter.aspx

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Text;
using System.IO;

public partial class XMLDemo : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Employee emp = new Employee();
        emp.FirstName = "Johnson";
        emp.LastName = "Yang";
        emp.Id = 1;

        SerilizerToXML(emp);

    }

    /// <summary>
    /// 把数据对象序列化到xml文件中
    /// </summary>
    /// <param name="obj">被序列化的数据对象</param>
    public static void SerilizerToXML(object obj)
    {
        XmlSerializer serilizer = new XmlSerializer(typeof(Employee));
        FileStream fStream = new FileStream(@"c:/CarData.xml",FileMode.Create, FileAccess.Write, FileShare.None);
        serilizer.Serialize(fStream, obj);
        fStream.Close();
    }

    public static Employee GetObjectFromXML(string xml)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Employee));
        System.IO.StringReader reader = new System.IO.StringReader(xml);
        Employee emp = (Employee)serializer.Deserialize(reader);
        return emp;
    }


}

 


持久化对象集合

      现在已经看到了如何将一个对象持久化为一个流,下面检验如何保存一组对象。IFormatter接口中的Serialize()方法不提供指定任意数量对象的方法(只能是单个的System.Object)。相关的是,Deserialize()方法的返回值一样也是单个的System.Object:
思路:System.Object实际上表现了一个完整的对象图,基于此,如果你传递进来一个被标记为[Serializable]的对象并且还包含了其他[Serializable]对象,整个对象集可以立刻被持久化。幸运的是,大多数在System.Collections和System.Collections.Generic命名空间内的类型已经被标记为[Serializable]。因此,如果你希望对一组对象进行持久化,只需要添加这组对象到容器(比如ArrayList或List<>)中并序列化对象为你选择的流就可以了。
Demo:ListSerialize.aspx

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public partial class ListSerialize : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //序列化
        Book book1 = new Book("C#编程基础", 90, "Tom");
        Book book2 = new Book("ASP.NET编程", 70, "Tom");
        Book book3 = new Book("数据库设计", 100, "Tom");

        ArrayList array = new ArrayList();
        array.Add(book1);
        array.Add(book2);
        array.Add(book3);

        IFormatter formatter = new BinaryFormatter();
        Stream stream = new FileStream(@"D:/myfile.dat", FileMode.Create, FileAccess.Write, FileShare.None);
        formatter.Serialize(stream,array);
        stream.Close();
        //反序列化
        BinaryFormatter form = new BinaryFormatter();
        Stream formstream = new FileStream(@"D:/myfile.dat", FileMode.Open, FileAccess.Read, FileShare.Read);
        //Deserialize返回值为object
        ArrayList obj = (ArrayList)formatter.Deserialize(formstream);
        formstream.Close();
        Response.Write(obj[1].ToString());
       
    }
}

  <?xml version="1.0" ?>
- <employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Id>1</Id>
  <FirstName>Johnson</FirstName>
  <LastName>Yang</LastName>
  <BirthDay>2009-12-08T11:43:33.1867576+08:00</BirthDay>
  </employee>