浅谈.Net框架下的序列化与反序列化

     在我们讨论序列化与反序列化之前,我们需要对这个名词有个大概的认识,序列化又称作串行化,序列化就是把一个对象保存到一个文件或数据库字段中去,反序列化就是在适当的时候把这个文件再转化成原来的对象使用。

     接着我们来谈谈序列化与反序列化的作用:1.可以以某种形式将对象持久化; 2.将对象从一个地方传递到另一个地方(比如进程间或平台间的传递)。

     最后我们俩一起看看.Net框架为我们准备好的3种序列化的方式,以及具体使用方式:

     1.使用BinaryFormatter进行序列化;

     2.使用SoapFormatter进行序列化;

     3.使用XmlFormatter进行序列化,与2类似,只是比Soap少了很多Soap自带的一些额外信息而已,也可将这两种看成是一类。

     可以使用[Serializable]属性将类标志为可序列化的。如果某个类的元素不想被序列化,1、2可以使用[NonSerialized]属性来标志,3可以使用[XmlIgnore]来标志。

     下面我们来逐个清点:

     1.BinaryFormatter

     序列化自定义类型

using System;

namespace Demo
{
    [Serializable]
    class People
    {
        public string Name { get; set; }
        public int Age { get; set; }   
    }
}
View Code

    序列化

FileStream fs = new FileStream(@"F:\GWork\WorkSpace\Serializable\demo-binary.xml",FileMode.Create);
            People p =new People(){Name = "Gavin",Age = 26};
            BinaryFormatter bf=new BinaryFormatter();
            bf.Serialize(fs,p);
            fs.Close();
View Code

    反序列化

FileStream fs = new FileStream(@"F:\GWork\WorkSpace\Serializable\demo-binary.xml",FileMode.Open);
            BinaryFormatter bf=new BinaryFormatter();
            People p= bf.Deserialize(fs) as People;
            if (p != null)
            {
                lbName.Text = p.Name;
                lbAge.Text = p.Age.ToString();
            }
            fs.Close();
View Code

    2.SoapFormatter

    这里标记序列化和1中是一样的;

    序列化

fs = new FileStream(@"F:\GWork\WorkSpace\Serializable\demo-soap.xml", FileMode.Create);
            SoapFormatter sf = new SoapFormatter();
            sf.Serialize(fs, p);
            fs.Close();
View Code

    反序列化

FileStream fs = new FileStream(@"F:\GWork\WorkSpace\Serializable\demo-soap.xml", FileMode.Open);
            SoapFormatter sf = new SoapFormatter();
            People p = sf.Deserialize(fs) as People;
            if (p != null)
            {
                lbName2.Text = p.Name;
                lbAge2.Text = p.Age.ToString();
            }
            fs.Close();
View Code

    3.XMLFormatter

    序列化自定义类型,这里无需增加Serializable标记

namespace Demo
{
    public class PeopleNonSerializeble
    {
        public string Name { get; set; }
        public int Age { get; set; }

        //public PeopleNonSerializeble()
        //{
                
        //}

        //public PeopleNonSerializeble(string name,int age)
        //{
        //    this.Name = name;
        //    this.Age = age;
        //}

        public override string ToString()
        {
            return string.Format("{0}:{1}",Name,Age);
        }
    }
}
View Code

     序列化

PeopleNonSerializeble pnSerializeble =new PeopleNonSerializeble(){Name = "Jerry",Age = 28};
            fs = new FileStream(@"F:\GWork\WorkSpace\Serializable\demo-xml.xml",FileMode.Create);
            XmlSerializer xs=new XmlSerializer(typeof(PeopleNonSerializeble));
            xs.Serialize(fs,pnSerializeble);
            fs.Close();
View Code

     反序列化

FileStream fs = new FileStream(@"F:\GWork\WorkSpace\Serializable\demo-xml.xml", FileMode.Open);
            XmlSerializer xs =new XmlSerializer(typeof(PeopleNonSerializeble));
            PeopleNonSerializeble p = xs.Deserialize(fs) as PeopleNonSerializeble;
            if (p != null)
            {
                lbName3.Text = p.Name;
                lbAge3.Text = p.Age.ToString();
            }
            fs.Close();
View Code

     介绍完了.Net框架给我们准备的标准格式化器之外,我们有时可能需要对我们的对象序列化的格式有一些特别的要求,比如小写转大小,英文日期格式转中文日期格式,外汇汇率转换等,那么这里另外一种序列化方式就诞生了,那就是自定义序列化格式器。

     自定义的序列化

     1.需要添加Serializable标记;

     2.需要实现:ISerializable接口;

     3.实现这个接口,就一个方法--GetObjectData,这个方法是将该对象序列化所需要的数据填充到SerializationInfo对象中;

     4.添加一个与GetObjectData相同签名的构造器,并且访问级别应该是受保护或私有的,目的就是防止粗心的Dev使用它。

     序列化自定义类型

using System;
using System.Runtime.Serialization;

namespace Demo
{
    [Serializable]
    class PeopleCustomizedSerializeble:ISerializable
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Address { get; set; }
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("n",Name.ToUpper());
            info.AddValue("a",Age);
            info.AddValue("add",Address.ToUpper());
        }

        public PeopleCustomizedSerializeble()
        {
                
        }
        protected PeopleCustomizedSerializeble(SerializationInfo info,StreamingContext context)
        {
            Name = info.GetString("n");
            Age = info.GetInt32("a");
            Address = info.GetString("add");
        }
    }
}
View Code

     序列化

PeopleCustomizedSerializeble peopleCustomized = new PeopleCustomizedSerializeble()
            {
                Address = "ah luan shch nangang shg",
                Age = 27,
                Name = "Jerry.King"
            };
            fs = new FileStream(@"F:\GWork\WorkSpace\Serializable\demo-Custom.xml", FileMode.Create);
            sf.Serialize(fs, peopleCustomized);
            fs.Close();
View Code

     反序列化

FileStream fs = new FileStream(@"F:\GWork\WorkSpace\Serializable\demo-Custom.xml", FileMode.Open);
            SoapFormatter xs = new SoapFormatter();
            PeopleCustomizedSerializeble p = xs.Deserialize(fs) as PeopleCustomizedSerializeble;
            if (p != null)
            {
                lbNameCust.Text = p.Name;
                lbAddCust.Text = p.Address;
            }
            fs.Close();
View Code

     以上,.Net中常用的几种序列化格式器都已经介绍完毕,但是故事还没完,既然有这么多种方式,那他们各自的优缺点是什么呢?性能比较?应用场景?OK,后续我们再来讨论这些问题。学知识不能浅尝辄止,要深入与实践。

 

posted @ 2015-10-25 11:02  Gavin.King  阅读(177)  评论(0)    收藏  举报