代码改变世界

序列化和反序列化

2015-04-08 10:28  糯米粥  阅读(698)  评论(0编辑  收藏  举报

什么是对象序列化?

  序列化(Serialization)是描述持久化一个对象的状态到流,如:文件流和内存流。的过程。被持久化的数据包括所有以后需要用来重建(即反序列化)对象状态所必需的信息。

 

定义可序列化的类型

  如果某个类需要被序列化。则必须标记为:[Serializable],如果有不想被序列化的字段,则标记为:[NonSerialized]

1     [Serializable]
2     public class UserPrefs
3     {
4         public string WindowColor;
5         public int FontSize;
6 
7         [NonSerialized]
8         public string id;
9     }

 

BinaryFormatter或SoapFormatter序列化时跟字段访问修饰符没关系,

但使用XmlSerializer序列化时,私有字段也不会被序列化,如果想被序列化。则定义为public,或者使用公共属性来封装私有字段

 1   [Serializable]
 2     public class UserPrefs
 3     {
 4         public string WindowColor;
 5         public int FontSize;
 6 
 7         [NonSerialized]
 8         public string id;
 9 
10         //私有字段也不会被序列化:
11         //如果想被序列化。则定义为public
12         //或者使用公共属性来封装私有字段
13         private string address;
14 
15 
16         private string name;
17         //公共属性来封装私有字段
18         public string Name
19         {
20             get { return name; }
21             set { name = value; }
22         }
23 
24     }

序列化格式:

一旦将类型配置为.Net可序列化,接下来就是选择当持久化对象时使用那种格式(二进制,SOAP或XML)

BinaryFormatter==>命名空间:

     System.Runtime.Serialization.Formatters.Binary; 属于二进制序列化

SoapFormatter==>命名空间:

     System.Runtime.Serialization.Formatters.Soap;

得先引用程序集(System.Runtime.Serialization.Formatters.Soap.dll)。属于SOAPX序列化

XmlSerializer==>命名空间:

     using System.Xml.Serialization;属于XML序列化,是基于标准的.Net Web服务可以被任何平台(不仅仅是.net)中的客户端调用。序列化的类必须是public类型,

     XmlSerializer要求对象图中所有的序列化类支持默认的构造函数:所以如果自定义有参的构造函数后。则一定要手动添加无参的构造函数。

 

格式化程序中的类型保真:

   在以上3种格式化程序中,最明显的不同是对象图(一组关联对象称为一个对象图)被持久化为不同的流(二进制,SOAP或XML)的方式,当使用BinaryFormatter类型时,不仅仅是就对象图中

对象的字段数据进行持久化,而且也持久化每个类型的完全限定名称和定义程序集的完整名称(名称,版本,公钥标记和区域性)。这些数据使BinaryFormatter在希望用值(例如以一个完整的副本)跨越

.Net应用程序机器边界传递对象时成为理想选择。

  如果希望持久化对象图可以被任意操作系统(xp,os,mac,Linux)应用程序框架(.net,java EE,COM)等编程语言使用,就不要保持完整的类型保真,因为不能假设所有可能的接收方都能理解.net专有的数据类型

基于此,当希望尽可能延伸持久化对象图的使用范围,SoapFormatter和XmlSerializer是最理想的选择。

 

序列化常用的关键方法:

   Serialize():将一个对象图按字节的顺序持久回到一个指定的流。

   Deserialize():将一个持久化的字节转化为一个对象图。

 

准备序列化的类:

 

 [Serializable]
     class UserPrefs
    {
        public string WindowColor;
        public int FontSize;
    }

添加默认数据:

   UserPrefs userData = new UserPrefs();
            userData.WindowColor = "Yellow";
            userData.FontSize = 50;

BinaryFormatter序列化

 //BinaryFormatter序列化
            //引用命名空间:System.Runtime.Serialization.Formatters.Binary;
            BinaryFormatter binFormat = new BinaryFormatter();

            //引用命名:System.IO;
            using (Stream fStream = new FileStream("user.txt", FileMode.Create, FileAccess.Write, FileShare.None))
            {
                binFormat.Serialize(fStream, userData);
                //Seri(new BinaryFormatter(), userData, userData);
            }
            //BinaryFormatter反序列化
            using (Stream fStream = File.OpenRead("user.txt"))
            {
                userData = binFormat.Deserialize(fStream) as UserPrefs;
            }

      //或者
 user u = new user { name = "你好",age="18"};

            var json = JsonConvert.SerializeObject(post);
            byte[] bytes;

            //序列化成二进制
            using(var stream = new MemoryStream())
            {
                new BinaryFormatter().Serialize(stream, u);
                bytes = stream.ToArray();
            }

结果:

              :iio, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null   
iio.UserPrefs   WindowColorFontSizeaddressname       Yellow2   



SoapFormatter序列化

 //SoapFormatter序列化
            //引用命名空间:System.Runtime.Serialization.Formatters.SOAP;
            SoapFormatter soap = new SoapFormatter();
            using (Stream s = File.Create("soap.soap"))
            {
                soap.Serialize(s, userData);
            }
            //SoapFormatter反序列化
            using (Stream s = File.OpenRead("soap.soap"))
            {
                userData = soap.Deserialize(s) as UserPrefs;
            }

结果:

<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/"> <SOAP-ENV:Body> <a1:UserPrefs id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/iio/iio%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull"> <WindowColor id="ref-3">Yellow</WindowColor> <FontSize>50</FontSize> <address xsi:null="1"/> <name xsi:null="1"/> </a1:UserPrefs> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

 

XmlSerializer序列化

 //XmlSerializer序列化
            //引用命名空间:System.Xml.Serialization;
            XmlSerializer xmlFormat = new XmlSerializer(typeof(UserPrefs));

            using (Stream s = File.Create("xml.xml"))
            {
                xmlFormat.Serialize(s, userData);
            }
            //XmlSerializer反序列化
            using (Stream s = File.OpenRead("xml.xml"))
            {
                userData = xmlFormat.Deserialize(s) as UserPrefs;
            }

结果:

<?xml version="1.0"?>
<UserPrefs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <WindowColor>Yellow</WindowColor>
  <FontSize>50</FontSize>
</UserPrefs>