C#序列化和反序列化之一

参考链接:

Xml序列化

C#序列化与反序列化(Serializable and Deserialize)

序列化和反序列化

C#序列化详解

C#编程总结(一)序列化

二进制序列化的优点:
  1. 所有的类成员(包括只读的)都可以被序列化;
  2. 性能非常好。
  
XML序列化的优点:

  1. 互操作性好;
  2. 不需要严格的二进制依赖;
  3. 可读性强。

下面的示例演示了,通过BinaryFormatter和XmlSerializer对对象进行(二进制和XML两种方式的)序列化和反序列化:

using System;
using System.Xml.Serialization;
using System.IO;
using System.Xml.Linq;
using System.Runtime.Serialization.Formatters.Binary;

namespace 序列化和反序列化
{
    [Serializable]
    public class Radio
    {
        private string _radioID = string.Empty;
        private bool _hasTweeters; // 扩音器
        [NonSerialized]
        public string Brand = string.Empty;
        [XmlIgnore]
        public string RadioID
        {
            get
            {
                return _radioID;
            }
        }

        public bool HasTweeters
        {
            get { return _hasTweeters; }
            set { _hasTweeters = value; }
        }

        /// <summary>
        /// ctor.
        /// </summary>
        /// <remarks>
        /// 1.要序列化的类必须有默认的构造的构造函数,才能使用XmlSerializer序列化
        /// </remarks>
        public Radio() { }
        public Radio(string radioID, bool hasTweeters)
        {
            _radioID = radioID;
            _hasTweeters = hasTweeters;
            Brand = "Panasonic";
        }
    }
    [Serializable]
    public class Car
    {
        public Radio radio { set; get; }
        public string Carname { set; get; }
        public string OwnerOfCar { set; get; }

        public virtual void Print()
        {
            Console.WriteLine("Carname = '{0}'", this.Carname);
            Console.WriteLine("OwnerOfCar = '{0}'", this.OwnerOfCar);
            Console.WriteLine("Radio.radioID = '{0}'", this.radio.RadioID);
            Console.WriteLine("Radio.hasTweeters = '{0}'", this.radio.HasTweeters);
            Console.WriteLine("Radio.Brand = '{0}'", this.radio.Brand);
        }

        /// <summary>
        /// ctor.
        /// </summary>
        /// <remarks>
        /// 1.要序列化的类必须有默认的构造的构造函数,才能使用XmlSerializer序列化
        /// </remarks>
        public Car() { }
    }
    [Serializable]
    public class ChineseCar : Car
    {
        public int MaxSpeed { set; get; }
        [XmlAttribute]
        public bool CanFly { set; get; } // CanFly作为xml属性存储

        public override void Print()
        {
            base.Print();
            Console.WriteLine("MaxSpeed = '{0}'", this.MaxSpeed);
            Console.WriteLine("CanFly = '{0}'", this.CanFly);
        }

        /// <summary>
        /// ctor.
        /// </summary>
        /// <remarks>
        /// 1.要序列化的类必须有默认的构造的构造函数,才能使用XmlSerializer序列化
        /// </remarks>
        public ChineseCar() { }
    }

    class Program
    {
        /// <summary>
        /// 序列化到xml中
        /// </summary>
        /// <param name="obj">持久化对象</param>
        /// <param name="filename">文件名</param>
        static void SerializeToXML(object obj, string filename)
        {
            XmlSerializer formatter = 
                new XmlSerializer(typeof(ChineseCar), new Type[] { typeof(Radio), typeof(Car) });
            using (FileStream stream = new FileStream(filename, FileMode.Create, FileAccess.Write))
            {
                try
                {
                    Console.WriteLine("Beginning Serialize...");
                    formatter.Serialize(stream, obj);
                    Console.WriteLine("Success");
                    Console.WriteLine("----------------------");
                }
                catch
                {
                    Console.WriteLine("Serialize fail!");
                }
            }

        }
        /// <summary>
        /// 从XML中反序列化
        /// </summary>
        /// <param name="filename">文件名</param>
        static object DeSerializeFormXML(string filename)
        {
            object obj = null;
            using (FileStream stream = new FileStream(filename, FileMode.Open))
            {
                try
                {
                    //formatter = new XmlSerializer(typeof(ChineseCar), new Type[] { typeof(Radio), typeof(Car) });
                    XmlSerializer formatter = new XmlSerializer(typeof(ChineseCar));
                    Console.WriteLine("Beginning Deserialize...");
                    obj = formatter.Deserialize(stream) as ChineseCar;
                    Console.WriteLine("Success");
                    Console.WriteLine("----------------------");

                }
                catch
                {
                    Console.WriteLine("Deserialize fail!");
                }
                finally
                {
                    stream.Close();
                }
            }
            return obj;
        }

        /// <summary>
        /// 读取xml
        /// </summary>
        /// <param name="filename">文件名</param>
        static void ShowXmlFile(string filename)
        {
            XElement root = XElement.Load(filename);
            Console.WriteLine(root);
        }

        /// <summary>
        /// 序列化到二进制文件
        /// </summary>
        /// <param name="obj">持久化对象</param>
        /// <param name="filename">文件名</param>
        static void SerializeToBinary(object obj,string filename)
        {
            using (Stream stream = File.Open(filename, FileMode.Create))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                Console.WriteLine("Beginning Serialize by Binary...");
                formatter.Serialize(stream, obj);
                Console.WriteLine("Success");
                Console.WriteLine("----------------------");
            }
        }
        /// <summary>
        /// 从二进制文件中反序列化
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <returns>返回反序列化的对象</returns>
        static object DeSerializeFormBinaryFile(string filename)
        {
            object obj = null;
            using (Stream stream = File.Open(filename, FileMode.Open))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                Console.WriteLine("Beginning Deserialize by Binary...");
                obj = (ChineseCar)formatter.Deserialize(stream);
                Console.WriteLine("Success");
                Console.WriteLine("----------------------");
            }
            return obj;
        }



        static void Main(string[] args)
        {
            ChineseCar obj = new ChineseCar()
            {
                CanFly = false,
                MaxSpeed = 200,

                Carname = "flying man",
                OwnerOfCar = "bobby",
                radio = new Radio("XX-BOBBY734", true)
            };


            SerializeToXML(obj, "Data.xml");                                    // XML序列化
            Console.WriteLine("输出xml文档内容:");
            ShowXmlFile("Data.xml");
            Console.WriteLine("----------------------");
            ChineseCar cc = DeSerializeFormXML("Data.xml") as ChineseCar;   // XML反序列化
            cc.Print();
            Console.WriteLine("----------------------");
            Console.WriteLine();

            SerializeToBinary(obj, "BinaryFile");                                       //二进制序列化
            Console.WriteLine("输出Binary文档内容:");
            Console.WriteLine("----------------------");
            ChineseCar cc1 = DeSerializeFormBinaryFile("BinaryFile") as ChineseCar;  // 二进制反序列化
            cc1.Print(); 

            Console.ReadLine();
        }
    }
}

请注意下面这段代码:

    [Serializable]
    public class Radio
    {
        private string _radioID = string.Empty;
        private bool _hasTweeters; // 扩音器
        [NonSerialized]
        public string Brand = string.Empty;
        [XmlIgnore]
        public string RadioID
        {
            get
            {
                return _radioID;
            }
        }

        public bool HasTweeters
        {
            get { return _hasTweeters; }
            set { _hasTweeters = value; }
        }

        /// <summary>
        /// ctor.
        /// </summary>
        /// <remarks>
        /// 1.要序列化的类必须有默认的构造的构造函数,才能使用XmlSerializer序列化
        /// </remarks>
        public Radio() { }
        public Radio(string radioID, bool hasTweeters)
        {
            _radioID = radioID;
            _hasTweeters = hasTweeters;
            Brand = "Panasonic";
        }
    }

  
  
  XmlIgnore描述的RadioID属性将在XmlSerializer持久化时被限制。在输出结果中能看到,Radio.radioID = ’ ‘,说明在XML序列化的时候忽略了对该字段的持久化,这点在生成的XML文档中也能够看到。
  NonSerialized修饰Brand字段,将在使用BinaryFormatter持久化时被限制。在输出结果中可以看到Radio.Brand=’ ’
输出结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值