分享

C# 串行化

 kittywei 2012-04-02

. 什么叫串行化?

串行化(Serialize)是指将对象存储到介质(如文件、内存缓冲区等)中或是以二进制方式通过网络传输。反串行化(Deserialize)指将这些连续的数据重新构建一个与原始对象状态相同的对象

2. 串行化分类两种形式

  • 二进制串行化

串行化时数据以二进制形式存入文件。但是该方式不适合同其他非.NET程序交换数据

  • XML串行化

对象的公共属性以XML元素和特性表示。该方式可以和其他非.NET程序交换数据。该方法要引用命名空间using System.Xml.Serialization;

另外,XML串行化器是不能针对枚举类型串行化操作的,如果有必要的话,可以将枚举型变量设置为私有变量,并且设置相应的简单类型变量进行操作。


3. 实例

     首先创建我们要串行化的类:

public class Book
{
     
public string _title;
     
public  int _page;
     
public string[] _Part;
     
public string _author;
     
public float _price;
}
  • 串行化对象
    void SerializeObject(Book[] book) 



    try 



    XmlSerializer ser 
    = new XmlSerializer(typeof(Book[]), new XmlRootAttribute("Books"));//声明对象,并且添加根节点 

    StreamWriter sw 
    = new StreamWriter("book.prt"); 

    ser.Serialize(sw, book); 

    sw.Close(); 



    catch (Exception e) 



    MessageBox.Show(
    "串行化失败:" + e.Message.ToString()); 



调用:

调用串行化

此时打开book.prt文件,如下图所示。

image

  • 反串行化方法
    private Book[] DeserializeObject() 



    FileStream fs 
    = new FileStream("book.prt", FileMode.Open); 

    XmlSerializer ser 
    = new XmlSerializer(typeof(Book[]), new XmlRootAttribute("Books")); 

    Book[] books 
    = (Book[])ser.Deserialize(fs); 

    return books; 

  • 概述:

    串行化(serialization)是指将一个对象的当前状态转换成字节流(a stream of bytes)的过程,而反串行化(deserialization)则指串行化过程的逆过程,将字节流转换成一个对象。初听起来可能对此不太感兴趣,但是使用串行化却有许多重要的原因。一旦将某一对象串行化,得到的字节可以存储在文件、数据库,或内存中——只要是可以存储的任何地方。需要恢复对象时,仅仅只需从它存储的位置反串行化即可。对象固有的这种特性对于无状态的Web应用程序是非常重要的,因为它允许重要的状态信息可以在用户请求之间保留。

    串行化也允许对象在应用程序边界之间传递,编程人员可以将描述对象状态的字节流在网络上传递,并在另一端反串行化成一个匹配的对象。从本质上讲,串行化允许对象以“数值”的方式传递给另一个应用程序。.NET远程框架广泛地在进程之间使用串行化来编组对象数据。

    串行化不是.NET新引入的概念,Windows程序员同各种各样的串行化打交道:MFC中的归档机制、Visuabl BasicPropertyBagCOMIPersistStream接口等,都具有类似的特性。那么.NET串行化与这些方式又有什么区别呢?一个字,简单。在.NET以前的开发环境中,串行化是一个手工定制,对于类设计人员来说,实现类的串行化并不困难,但是实现难度较大的设计,它就显得能麻烦、耗时。在.NET中,该过程完全是自动进行的,用户所做的就是使用Serializable特性来标记一个能串行化的类,运行库做余下的事。

    .NET运行库怎样实现这一捷径的呢?当然是利用镜像,或更为准确地说是反射。前面提到,程序集含有名为元数据的自描述(self-describing)数据,程序集的元数据完整地表述了内部每一个类型,包括类型中每个私有字段的信息。通过反射过程,运行库能识别元数据,并用它来决定类应怎样被串行化。

    使用Serializable特性实现串行化:
    前面已经提到,如果允许运行库串行化一个对象,必须将该类标记上
    Serializable特性。下面的代码定义了两个标记了Serialable特性的类。

    [Serializable]

    public class Car

    {

    private string mColor;

    private int mTopSpeed;

    //Reference to another object

    private Radio mRadio;

    [NonSerialized] //Runtime will not serialize this field

    private string mNickName;

    public Car(string nickName, int topSpeed, string color)

    {

    mNickName = nickName;

    mTopSpeed = topSpeed;

    mColor = color;

    mRadio = new Radio();

    }

    }

    [Serializable]

    public class Radio

    {

    private int mVolume = 5;

    }

    如上所示,Car类的mNickName字段用NonSerialized特性标注,指示运行库进行串行化时跳过该项,而其他部分允许进行串行化。这里注意,mRadio是对另一对象的引用,意味着运行库必须对其串行化。事实上,当运行库被告知要对某个对象串行化时,使用给定的对象作为根,建立一个对象图表(类似于垃圾回收器)。所有在图表中的对象也必须可被串行化的,否则运行库将引发异常。

    下面的代码举例说明如何将Car对象串行化到一个文件之中。

    static void Main(string[] args)

    {

    Car myCar = new Car("Christine", 150, "Red");

    FileStream mySoapFile = File.Create("Car.txt");

    // Use a SOAP formatter object to serialize the object.

    new SoapFormatter().Serialize(mySoapFile, myCar);

    mySoapFile.Close();

    }

    运行库不控制串行化数据的实际格式,但是有一个专门进行格式化的对象负责对串行化输出进行格式化。.NET框架有两种格式化程序:SOAP格式化程序和二进制格式化程序。在前面的例子中,SoapFormatter对象将对象串行化进一个SOAP报文,并将其发送到特定的流中。图2-26显示了在执行完这段代码后Car.txt中的内容。

    如果仔细查看图2-26,很容易发现SOAP是如何描绘每个对象和它的数据成员。这种方式通过增加文件大小来提高了可读性。二进制格式化程序使用了更为紧凑的格式。如果需要在网络间发送对象,这种方式就更重要,尤其是在需要考虑网络带宽而不强调可读性的情况下。

    通过调用SoapFormatter.Dewerialize方法,就可将该对象读入内存中:

    static void Rehydrate()

    {

    FileStream mySoapFile = File.Open("Car.txt", FileMode.Open);

    Car myCar = (Car) new SoapFormatter().Deserialize(mySoapFile);

    mySoapFile.Close();

    }

    2-26  使用SOAP格式化程序对Car对象进行串行化

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多