对象序列化 BinaryFormatter、XmlSerializer、SoapFormatter

序列化:持久化(可能还包括传输)一个对象的状态到流(如文件流和内存流)的过程。
        用最小花费来保存海量的(各种格式的)数据就变的轻而易举。

序列化是用来通信的,服务端把数据序列化,发送到客户端,客户端把接收到的数据反序列化后对数据进行操作,完成后再序列化发送到服务端,服务端再反序列化数据后对数据进行操作。
 序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据

序列化    :将对象状态转换为可保持或传输的格式的过程。
反序列化:它将流转换为对象。


    这两个过程结合起来,可以轻松地存储和传输数据。例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象。反之,反序列化根据流重新构造对象。此外还可以将对象序列化后保存到本地,再次运行的时候可以从本地文件中“恢复”对象到序列化之前的状态。

    在.net中有提供了几种序列化的方式:
      1、二进制序列化
      2、XML序列化
      3、SOAP序列化

二进制序列化
       所谓二进制序列化,指的是对象序列化之后是二进制形式的。二进制序列化是通过 BinaryFormatter 类来实现的。
       这个类位于System.Runtime.Serialization.Formatters.Binary命名空间下。

XML序列化
       所谓XML序列化,是指对象序列化之后的结果是XML形式的。保存XML序列化是通过 XmlSerializer  类来实现的。
       这个类位于System.Xml.Serialization命名空间下。

SOAP序列化
       所谓SOAP序列化是指对象序列化之后的结果符合SOAP协议,也就是可以通过SOAP协议传输(不知道SOAP协议?百度一下吧)。
       SOAP序列化是通过 SoapFormatter 类来实现的。
        这个类位于System.Runtime.Serialization.Formatters.Soap命名空间下,并且需要注意需要手动添加对这个命名空间的引用,如下图所示:

 

 

一、序列化【存储】

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;//二进制序列化
using System.Xml.Serialization;//XML序列化
using System.Runtime.Serialization.Formatters.Soap;//soap序列化
namespace ConsoleApplication2
{
    [Serializable]
    public class MyObject
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public override string ToString()
        {
            return String.Format("姓名:{0}", name);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyObject obj = new MyObject();   
            obj.Name = "小张";
            Console.WriteLine("========使用BinaryFormatter类进行序列化和反序列化。====");  
            BinarySerialize(obj);
            BinaryDeserialize("C://MyObject.dat");
            Console.WriteLine("========使用SoapFormatter类进行序列化和反序列化。====");
            SOAPSerialize(obj);
            SOAPDeserialize("C://MyObject.soap");
            Console.WriteLine("========使用XmlSerializer类进行序列化和反序列化。====");
            XMLSerialize(obj);
            XMLDeserialize("C://MyObject.xml");  


            Console.ReadKey();
        }

        /// 
        /// 二进制序列化对象
        /// 
        /// 
        public static void BinarySerialize(MyObject obj)
        {
            using (FileStream stream = new FileStream("C://MyObject.dat",FileMode.Create,FileAccess.Write))
           {
               BinaryFormatter formater = new BinaryFormatter();
               formater.Serialize(stream,obj);
               Console.WriteLine("对象已经被序列化。" + obj.ToString());  
           }
        }

        /// 
        /// 二进制反序列化
        /// 
        /// 
        public static void BinaryDeserialize(string fileName)
        {
            using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                BinaryFormatter formater = new BinaryFormatter();
                MyObject obj = (MyObject)formater.Deserialize(stream);
                Console.WriteLine("对象已经被反序列化。" + obj.ToString());
            }
        }

        /// 
        /// soap序列化对象
        /// 
        /// 
        public static void SOAPSerialize(MyObject obj)
        {
            using (FileStream stream = new FileStream("C://MyObject.soap", FileMode.Create, FileAccess.Write))
            {
                SoapFormatter formater = new SoapFormatter();
                formater.Serialize(stream, obj);
                Console.WriteLine("对象已经被序列化。" + obj.ToString());
            }
        }
        /// 
        /// soap反序列化
        /// 
        /// 
        public static void SOAPDeserialize(string fileName)
        {
            using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                SoapFormatter formater = new SoapFormatter();
                MyObject obj = (MyObject)formater.Deserialize(stream);
                Console.WriteLine("对象已经被反序列化。" + obj.ToString());
            }
        }

        /// 
        /// XML序列化
        /// 
        /// 
        public static void XMLSerialize(MyObject obj)
        {
            using (FileStream stream = new FileStream("C://MyObject.xml", FileMode.Create, FileAccess.Write))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
                serializer.Serialize(stream, obj);
                Console.WriteLine("对象已经被序列化。" + obj.ToString());
            }
        }
        /// 
        /// XML反序列化
        /// 
        /// 
        public static void XMLDeserialize(string fileName)
        {
            using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
                MyObject obj = (MyObject)serializer.Deserialize(stream);
                Console.WriteLine("对象已经被反序列化。" + obj.ToString());
            }
        }

    }

    

}


 

 

效果:

 

序列化意义所在,能保存对象运行时的状态并且还能还原。

 

二、序列化【传输】

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// 
/// ObjModel 的摘要说明
/// 
[Serializable]
public class ObjModel
{
    public String Name { get; set; }
    public String Value { get; set; }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Serialization;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ObjModel obj = new ObjModel();
        obj.Name = "姓名";
        Deserialize(Serialiaze(obj),typeof(ObjModel));
    }
  

    /// 
    /// 序列化成字符串
    /// 
    /// 
    /// 序列化后的字符串
    public static string Serialiaze(object obj)
    {
        XmlSerializer xs = new XmlSerializer(obj.GetType());
        MemoryStream ms = new MemoryStream();
        XmlTextWriter xtw = new XmlTextWriter(ms, System.Text.Encoding.UTF8);
        xtw.Formatting = Formatting.Indented;
        xs.Serialize(xtw, obj);
        ms.Seek(0, SeekOrigin.Begin);
        StreamReader sr = new StreamReader(ms);
        string str = sr.ReadToEnd();
        xtw.Close();
        ms.Close();
        return str;
    }

    /// 
    /// 反序列化 从字符串
    /// 
    /// xml字符串
    /// 要生成的对象类型
    /// 反序列化后的对象
    public static object Deserialize(string xml, Type type)
    {
        XmlSerializer xs = new XmlSerializer(type);
        StringReader sr = new StringReader(xml);
        object obj = xs.Deserialize(sr);
        return obj;
    }
}


三、控制生成的XML数据

对象序列化 BinaryFormatter、XmlSerializer、SoapFormatter_第1张图片

1、MODEL

        [Serializable]
        public class Radio //音乐
        {
            //高音扬声器
            public bool hasTweeters;
            //低音炮
            public bool hasSubWoofers;
            //配置设置
            public double[] stationPresets;

            [NonSerialized]
            public string radioID = "XF-552RR6";
        }
        [Serializable]
        public class Car
        {
            public Radio theRadio = new Radio();
            public bool isHatchBack;//掀背车
        }
        [Serializable,
        XmlRoot(Namespace="http://www.MyCompany.com")]
        public class JamesBondCar : Car//007中德邦的车
        {
            [XmlAttribute]
            public bool canFly;
            [XmlAttribute]
            public bool canSubmerge;
        }

        [Serializable,
        XmlRoot(Namespace="http://www.MyCompany.com")]
        public class JamesBondCar : Car//007中德邦的车
        {
            [XmlAttribute]
            public bool canFly;
            [XmlAttribute]
            public bool canSubmerge;
        }

 2、序列化XML

            JamesBondCar jbc = new JamesBondCar();
            jbc.canFly = true;
            jbc.canSubmerge = false;
            jbc.theRadio.stationPresets = new double[] { 89.3,105.1,97.1};
            jbc.theRadio.hasTweeters = true;

            using (FileStream fs = new FileStream("JamesBondCar.xml", FileMode.Create, FileAccess.Write))
           {
               XmlSerializer formatter = new XmlSerializer(typeof(JamesBondCar));
               formatter.Serialize(fs, jbc);
           }

3、JamesBondCar.xml


canFly="true"
canSubmerge="false"
xmlns="http://www.MyCompany.com"
>
 
    true
    false
   
      89.3
      105.1
      97.1
   

    XF-552RR6
 

  false



四、序列化对象集合

        序列化对象集合:对一组对象进行持久化。
        只需要添加这组对象到容器(比如ArrayList或List)中并序列化对象为你选择的流。


1、Model

        [Serializable]
        public class Radio //音乐
        {
            //高音扬声器
            public bool hasTweeters;
            //低音炮
            public bool hasSubWoofers;
            //配置设置
            public double[] stationPresets;

            [NonSerialized]
            public string radioID = "XF-552RR6";
        }
        [Serializable]
        public class Car
        {
            public Radio theRadio = new Radio();
            public bool isHatchBack;//掀背车
        }
        [Serializable,
        XmlRoot(Namespace="http://www.MyCompany.com")]
        public class JamesBondCar : Car//007中德邦的车
        {
            public JamesBondCar(bool skyWorthy,bool seaWorthy)
            {
                canFly = skyWorthy;
                canSubmerge = seaWorthy;
            }
            //XmlSerializer 需要一个默认构造函数
            public JamesBondCar() { }


            [XmlAttribute]
            public bool canFly;
            [XmlAttribute]
            public bool canSubmerge;
        }


2、对象集合序列化 XML

            List myCars = new List();
            myCars.Add(new JamesBondCar(true,true));
            myCars.Add(new JamesBondCar(true, false));
            myCars.Add(new JamesBondCar(false,true));
            myCars.Add(new JamesBondCar(false,false));
            using (FileStream fs = new FileStream("JamesBondCar.xml", FileMode.Create, FileAccess.Write))
           {
               XmlSerializer formatter = new XmlSerializer(typeof(List));
               formatter.Serialize(fs, myCars);
           }


3、JamesBondCar.sml



  
    
      false
      false
      XF-552RR6
    
    false
  
  
    
      false
      false
      XF-552RR6
    
    false
  
  
    
      false
      false
      XF-552RR6
    
    false
  
  
    
      false
      false
      XF-552RR6
    
    false
  


五、自定义Soap/Binary序列化(推荐 特性定制序列化)

            序列化过程中更多的 干预构造处理目录树的过程

           参与对象序列化的过程,System.Runtime.Serialization 命名空间提供以下几种类型:

对象序列化 BinaryFormatter、XmlSerializer、SoapFormatter_第2张图片

1、使用 ISerializable 自定义序列化

      被标记了[Serializable]的对象,拥有了实现ISerializable接口选项,序列化过程前 序列化后 数据格式

        [Serializable]
        class StringData : ISerializable
        {
            private string dataItemOne = "First data block";
            private string dataItemTwo = "More data";
            public StringData() { }
            protected StringData(SerializationInfo si, StreamingContext ctx)
            {
                //从流中得到合并的成员变量
                dataItemOne = si.GetString("First_Item").ToLower();
                dataItemTwo = si.GetString("dataItemTwo").ToLower();
            }
            //实现ISerializable接口方法(字段数据必须持久化为大写格式)
            void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
            {
                //用格式化数据填充 SerializationInfo
                info.AddValue("First_Item", dataItemOne.ToUpper());
                info.AddValue("dataItemTwo", dataItemTwo.ToUpper());
            }
        }


序列化soap

            StringData MyDate = new StringData();
            using (FileStream fs = new FileStream("StringData.soap", FileMode.Create, FileAccess.Write))
            {
                SoapFormatter formatter = new SoapFormatter();
                formatter.Serialize(fs, MyDate);
            }


2、使用特性定制序列化

            自.net 2.0 发布以来,定制序列化过程首选是【特性】不需要手动与输入的SerializationInfo参数交互
            如 

                  [OnSerializing] 允许指定方法在对象被序列化之前调用
                  [OnSerialized]  允许指定方法在对象被序列化之后立即被调用
                  [OnDeserializing] ............对象被反序列化之前调用
                  [OnDeserialized]  ............对象被反序列化之后立即被调用


   应用这个特性,必须定义方法接收一个 StreamingContext 参数并返回空

        [Serializable]
        class StringData
        {
            private string dataItemOne = "First data block";
            private string dataItemTwo = "More data";

            [OnSerializing]
            private void OnSerializing(StreamingContext context)
            {
                //序列化过程中,就得调用
                dataItemOne = dataItemOne.ToUpper();
                dataItemTwo = dataItemTwo.ToUpper();
            }

            [OnDeserialized]
            private void OnDeserialized(StreamingContext context)
            {
                //一但反序列化过程结束,就得调用
                dataItemOne = dataItemOne.ToLower();
                dataItemTwo = dataItemTwo.ToLower();
            }
        }




转载自:http://blog.csdn.net/zhoufoxcn/article/details/3978874

 

你可能感兴趣的:(C#)