zoukankan      html  css  js  c++  java
  • 初识序列化和反序列化,使用BinaryFormatter类、ISerializable接口、XmlSerializer类进行序列化和反序列化

    序列化是将对象转换成字节流的过程,反序列化是把字节流转换成对象的过程。对象一旦被序列化,就可以把对象状态保存到硬盘的某个位置,甚至还可以通过网络发送给另外一台机器上运行的进程。本篇主要包括:

     

    使用BinaryFormatter类进行序列化和反序列化
    使用ISerializable接口自定义序列化过程
    使用XmlSerializer类进行序列化和反序列化

     

    □ 使用BinaryFormatter类进行序列化和反序列化

     

    首先把需要序列化的类打上[Serializable]特性,如果某个字段不需要被序列化,就打上[NonSerialized]特性。

     

        [Serializable]
    
        public class Meeting
    
        {
    
            public string _name;
    
            [NonSerialized]
    
            public string _location;
    
            public Meeting(string name, string location)
    
            {
    
                this._name = name;
    
                this._location = location;
    
            }
    
        }
    

     

    对象序列化后需要一个载体文件,以下的Meeting.binary文件用来存储对象的状态。

     

            static void Main(string[] args)
    
            {
    
                Meeting m1 = new Meeting("年终总结","青岛");
    
                Meeting m2;
    
                //先序列化
    
                SerializedWithBinaryFormatter(m1,"Meeting.binary");
    
                m2 = (Meeting) DeserializeWithBinaryFormatter("Meeting.binary");
    
                Console.WriteLine(m2._name);
    
                Console.WriteLine(m2._location  ?? "_location字段没有被序列化");
    
                Console.ReadKey();
    
            }
    
            //序列化
    
            static void SerializedWithBinaryFormatter(object obj, string fileName)
    
            {
    
                //打开文件写成流
    
                Stream streamOut = File.OpenWrite(fileName);
    
                BinaryFormatter formatter = new BinaryFormatter();
    
                //把对象序列化到流中
    
                formatter.Serialize(streamOut, obj);
    
                //关闭流
    
                streamOut.Close();
    
            }
    
            //反序列化
    
            static object DeserializeWithBinaryFormatter(string fileName)
    
            {
    
                //打开文件读成流
    
                Stream streamIn = File.OpenRead(fileName);
    
                BinaryFormatter formatter = new BinaryFormatter();
    
                object obj = formatter.Deserialize(streamIn);
    
                streamIn.Close();
    
                return obj;
    
            }   
    

    Meeting.binary文件在bin/debug文件夹中。 

     

    □ 使用ISerializable接口自定义序列化过程

     

    如果想对序列化的过程有更多的控制,应该使用ISerializable接口,通过它的GetObjectData方法可以改变对象的字段值。

     

      [Serializable]
    
        public class Location : ISerializable
    
        {
    
            public int x;
    
            public int y;
    
            public string name;
    
            public Location(int x, int y, string name)
    
            {
    
                this.x = x;
    
                this.y = y;
    
                this.name = name;
    
            }
    
            protected Location(SerializationInfo info, StreamingContext context)
    
            {
    
                x = info.GetInt32("i");
    
                y = info.GetInt32("j");
    
                name = info.GetString("k");
    
            }
    
            public void GetObjectData(SerializationInfo info, StreamingContext context)
    
            {
    
                info.AddValue("i", x + 1);
    
                info.AddValue("j", y + 1);
    
                info.AddValue("k", name + "HELLO");
    
            }
    
        }
    

    以上,不仅要实现接口方法GetObjectData,还需要提供对象的重载构造函数,从SerializationInfo实例中获取值。

     

    在客户端:   

     

                Location loc1 = new Location(1,2,"qingdao");
    
                Location loc2;
    
                //序列化
    
                SerializedWithBinaryFormatter(loc1, "Location.binary");
    
                loc2 = (Location) DeserializeWithBinaryFormatter("Location.binary");
    
                Console.WriteLine(loc2.x);
    
                Console.WriteLine(loc2.y);
    
                Console.WriteLine(loc2.name);
    
                Console.ReadKey();   
    

    以上,使用BinaryFormatter类进行序列化和反序列化,存储的文件格式是二进制的,例如,打开Meeting.binary文件,我们看到:

    1

    有时候,我们希望文件的格式是xml。

     

    □ 使用XmlSerializer类进行序列化和反序列化

     

    XmlSerializer类进行序列化的存储文件是xml格式。用XmlSerializer类进行序列化的类不需要打上[Serializable]特性。

     

        public class Car
    
        {
    
            [XmlAttribute(AttributeName = "model")]
    
            public string type;
    
            public string code;
    
            [XmlIgnore]
    
            public int age;
    
            [XmlElement(ElementName = "mileage")]
    
            public int miles;
    
            public Status status;
    
            public enum Status
    
            {
    
                [XmlEnum("使用中")]
    
                Normal,
    
                [XmlEnum("修复中")]
    
                NotUse,
    
                [XmlEnum("不再使用")]
    
                Deleted
    
            }
    
        }
    

     

    在客户端:

     

                //打开写进流
    
                Stream streamOut = File.OpenWrite("Car.xml");
    
                System.Xml.Serialization.XmlSerializer x = new XmlSerializer(car1.GetType());
    
                //序列化到流中
    
                x.Serialize(streamOut, car1);
    
                streamOut.Close();
    
                //打开读流
    
                Stream streamIn = File.OpenRead("Car.xml");
    
                //反序列化
    
                Car car2 = (Car) x.Deserialize(streamIn);
    
                Console.WriteLine(car2.type);
    
                Console.WriteLine(car2.code);
    
                Console.WriteLine(car2.miles);
    
                Console.WriteLine(car2.status);
    
                Console.ReadKey();    
    

     

    运行,打开bin/debug中的Car.xml文件如下:

    <?xml version="1.0"?>
    
    <Car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" model="sedan">
    
      <code>001</code>
    
      <mileage>1000</mileage>
    
      <status>使用中</status>
    
    </Car>

    ○ 类名Car成了xml的根节点
    ○ 打上[XmlAttribute(AttributeName = "model")]特性的字段变成了根节点的属性,AttributeName为属性别名
    ○ 枚举项可打上[XmlEnum("使用中")]特性

     

    如果一个类中包含集合属性,比如以下的Department类包含一个类型List<Employee>的集合属性Employees。


       public class Department
    
        {
    
            public Department()
    
            {
    
                Employees = new List<Employee>();
    
            }
    
            public string Name { get; set; }
    
            [XmlArray("Staff")]
    
            public List<Employee> Employees { get; set; }
    
        }
    
        public class Employee
    
        {
    
            public string Name { get; set; }
    
            public Employee()
    
            {
    
                
    
            }
    
            public Employee(string name)
    
            {
    
                Name = name;
    
            }
    
        }
    

     

    在客户端:   

     

        class Program
    
        {
    
            static void Main(string[] args)
    
            {
    
                var department = new Department();
    
                department.Name = "销售部";
    
                department.Employees.Add(new Employee("张三"));
    
                department.Employees.Add(new Employee("李四"));
    
                XmlSerializer serializer = new XmlSerializer(department.GetType());
    
                //打开写进流
    
                Stream streamOut = File.OpenWrite("Department.xml");
    
                serializer.Serialize(streamOut, department);
    
                streamOut.Close();
    
            }
    
        }   
    

    查看bin/debug中的Department.xml文件。

     

    <?xml version="1.0"?>
    
    <Department xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    
      <Name>销售部</Name>
    
      <Staff>
    
        <Employee>
    
          <Name>张三</Name>
    
        </Employee>
    
        <Employee>
    
          <Name>李四</Name>
    
        </Employee>
    
      </Staff>
    
    </Department>

     

    总结:
    1、使用BinaryFormatter类序列化到二进制文件
    2、使用XmlSerializer类序列化到xml文件
    3、使用ISerializable接口自定义序列化过程

  • 相关阅读:
    Android Activity 四种启动模式
    Android Activity的生命周期
    Android SQLite (五 ) 全面详解(三)
    Android SQLite (四 ) 全面详解(二)
    工作流设计 zt
    法律网站分类 ­zt
    刑事案件的构成要素 zt
    犯罪构成三层次记忆口诀 zt
    E asy Boo t 6.51 启动易 制作启动光盘的软件(附注册码)
    父线程开启子进程且共享内存
  • 原文地址:https://www.cnblogs.com/darrenji/p/4251611.html
Copyright © 2011-2022 走看看