• 序列化与反序列化


    序列化就是把对象状态转换成二进制流形式,以供保存或传输.保存就是保存在物理存储介质上,传输是指在网络中传输.反序列化与序列化相反,就是从物理存储介质或流上读出数据,并还原成一个对象.序列化有两大用处:一个是把对象状态保存到存储介质上,以便以后可以还复(重新读取)该对象.第二个就是把对象序列化以后,从一个应用程序域传到另一个应用程序域进行处理.
    按照msdn的示例写了一个简单的测试程序,发现序列化真的很好用.

    Class1的源码(包括二进制序列化和xml集合类的序列化):

    ///


     /// Class1 的摘要说明。
     ///

     class Class1
     {
      ///
      /// 应用程序的主入口点。
      ///

      [STAThread]
      static void Main(string[] args)
      {
       
        
         
      
       //Serialize();
       //Deserialize();
       //SerializeCollection("c:\\xmlSeriali.xml");
       DeSerializeCollection("c:\\xmlSeriali.xml");
      }

     public static void Serialize()
     {
      MyObject obj = new MyObject();
      obj.n1 = 1;
      obj.n2 = 24;
      obj.str = "我是一个小兵";
      IFormatter formatter = new SoapFormatter();
      Stream stream = new FileStream("c:\\MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None);
      formatter.Serialize(stream, obj);
      stream.Close();
     }


     public static void Deserialize()
     {
      IFormatter formatter = new SoapFormatter();
      Stream stream = new FileStream("c:\\MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
      MyObject obj = (MyObject) formatter.Deserialize(stream);
      stream.Close();

     // Here's the proof.
     Console.WriteLine("n1: {0}", obj.n1);
     Console.WriteLine("n2: {0}", obj.n2);
     Console.WriteLine("str: {0}", obj.str);
     Console.ReadLine();
     }

     private static void SerializeCollection(string filename)
     {
      MyLists Emps = new MyLists();
      // Note that only the collection is serialized--not the
      // CollectionName or any other public property of the class.
      Emps.CollectionName = "Employees";
      MyConfig John100 = new MyConfig("John", "100xxx");
      Emps.Add(John100);
      MyConfig cyc = new MyConfig("connection", "cyc/df");
      Emps.Add(cyc);
      XmlSerializer x = new XmlSerializer(typeof(MyLists));
      TextWriter writer = new StreamWriter(filename);
      x.Serialize(writer, Emps);
     }

     private static void DeSerializeCollection(string filename)
     {
      XmlSerializer serializer = new
       XmlSerializer(typeof(MyLists));

     // A FileStream is needed to read the XML document.
     FileStream fs = new FileStream(filename, FileMode.Open);
     XmlReader reader = new XmlTextReader(fs);
     
      // Declare an object variable of the type to be deserialized.
      MyLists mls=(MyLists) serializer.Deserialize(reader);
      foreach (MyConfig mc in mls)
      {
       Console.WriteLine(mc.Key);
       Console.WriteLine(mc.KeyValue);
      }
      Console.ReadLine();

     }
     
    MyObject类源码:

    [Serializable]
     public class MyObject
     {
      
       
     
      public int n1 = 0;
      public int n2 = 0;
      public String str = null;
       
        

     }

    MyConfig类的源码(具体的项类):

    ///


     /// MyList 的摘要说明。
     ///

     public class MyConfig
     {
      private string _Key,_KeyValue;
       
      public MyConfig()
      {
       
        
         
      }

     public MyConfig(string Key,string KeyValue)
     {
      _Key=Key;
      _KeyValue=KeyValue;
     }


     public string Key
     {
      get
      {
       return _Key;
      }
      set
      {
       _Key=value;
      }
     }

     public string KeyValue
     {
      get
      {
       return _KeyValue;
      }
      set
      {
       _KeyValue=value;
      }
     }

    }

    MyLists类的源码(集合类,是MyConfig类的集合):

    ///


     /// MyLists 的摘要说明。
     ///

     public class MyLists : ICollection
     {
      private ArrayList al=new ArrayList();
      public string CollectionName;


     public MyLists()
     {
      //
      // TODO: 在此处添加构造函数逻辑
      //
     }
     #region ICollection 成员

     public bool IsSynchronized
     {
      get
      {
       // TODO:  添加 MyLists.IsSynchronized getter 实现
       return false;
      }
     }

     public int Count
     {
      get
      {
       // TODO:  添加 MyLists.Count getter 实现
       return al.Count;
      }
     }

     public void CopyTo(Array array, int index)
     {
      // TODO:  添加 MyLists.CopyTo 实现
     }

     public object SyncRoot
     {
      get
      {
       // TODO:  添加 MyLists.SyncRoot getter 实现
       return this;
      }
     }

     #endregion

     #region IEnumerable 成员

     public IEnumerator GetEnumerator()
     {
      // TODO:  添加 MyLists.GetEnumerator 实现
      return al.GetEnumerator();
     }

     #endregion

     public void Add(MyConfig ml)
     {
      al.Add(ml);
     }

     public MyConfig this[int index]
     {
      get
      {
       return (MyConfig)al[index];
      }
      set
      {
       al[index]=value;
      }
     }
     }


    XML 序列化将对象的公共字段和属性或者方法的参数和返回值转换(序列化)为符合特定 XML 架构定义语言 (XSD) 文档的 XML 流。XML 序列化产生强类型类,并为存储或传输目的将其公共属性和字段转换为序列格式(在此情况下,为 XML)。XML 序列化还可用于将对象序列化为符合 SOAP 规范的 XML 流。SOAP 是一种基于 XML 的协议,它是专门为使用 XML 来传输过程调用而设计的。
    使用 XmLSerializer 类,可将下列项序列化。
     · 公共类的公共读/写属性和字段
     · 实现 ICollection 或 IEnumerable 的类。(注意只有集合会被序列化,而公共属性却不会。)
     · XmlElement 对象。
     · XmlNode 对象。
     · DataSet 对象。
    实现 ICollection 或 IEnumerable 的类的序列化要特殊一点,而在url rewrite那篇文章中用的就是实现了ICollection接口的CollectionBase类作为基类,所以我才来看序列化的东西.xml序列化能很好的解决的自定义配置节或自定义配置文件的问题,所以值得研究.另外序列化对研究Web Services也是很有帮助的. Web services中传输数据也是要先序列化对象为xml流,然后在另一端进行反序列化还原数据.xml序列化可以通过
    指定xsd(xml架构文件)来序列化一个对象,也可以在类文件的各个属性或字段是用Attribute特性来指定其在序列化时生成的元素名(xml element name)等其它信息.反序列化时必须强制把返回的对象(object)对象转换成相应的类.
    以下引用下面的这篇文章:
    http://blog.csdn.net/21aspnet/archive/2004/11/04/167441.aspx

    从上图可以很直观的理解xml序列化的问题.
    再来看urlrewrite那篇文章的源码,首先是RewriterConfigSerializerSectionHandler类,它实现了IConfigurationSectionHandler接口,用于处理自定的配置节RewriterConfig,它调用XmlSerializer对象的Deserialize方法反序列化成一个RewriterConfiguration对象,RewriterConfiguration类中定义了一个rules属性,对应于配置节中的配置节.RewriterConfiguration类应用了Serializable特性和XmlRoot("RewriterConfig")特性,指定该类可被序列化,并且以RewriterConfig节为根.其中的GetConfig()方法调用了ConfigurationSettings.GetConfig("RewriterConfig")方法,ConfigurationSettings类的GetConfig()方法根据配置节:

     



    找到处理RewriteCofig配置节的处理类,也就是实现了IConfigurationSectionHandler接口的URLRewriter.Config.RewriterConfigSerializerSectionHandler类,然后调用该类的Create方法返回一个配置类也就是RewriterConfiguration类;从中可以看出RewriterConfiguration和RewriterConfigSerializerSectionHandle类是相互引用的.开始理解这个时候是不是有点头晕.我也是.
    而在RewriterConfiguration中实际返回的结果是rules属性,也就是RewriterRuleCollection集合类,该类从CollectionBase类中继承,CollectionBase类实现了Ilist,Icollection,IEnumerable接口.序列化集合类与普通的类的序列化不大一样,集合类由两个类组成,一个是集合类(Collection Class ), 另一个是项类(Item Class).序列化集合类会把重复的项的放到集合类中,并要定义一个项类,具体的参见上面的示例代码或者msdn.项类的每一个属性都对应于重复项中的一个Element.
    注:urlrewrite文章的源码下次贴出来,觉得可能没有多大的必要,因为大家都可以到微软的网站上下.是不是呢?

  • 相关阅读:
    hiho一下 第115周:网络流一•Ford-Fulkerson算法 (Edmond-Karp,Dinic,SAP)
    hiho一下 第二周&第四周:从Trie树到Trie图
    2016 acm香港网络赛 C题. Classrooms(贪心)
    2016 acm香港网络赛 F题. Crazy Driver(水题)
    2016 acm香港网络赛 B题. Boxes
    系统吞吐量(TPS)、用户并发量、性能测试概念和公式(转发)
    使Eclipse下支持编写HTML/JS/CSS/JSP页面的自动提示。
    Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析
    Tomcat 系统架构与设计模式,第 1 部分: 工作原理
    Tomcat源码分析
  • 原文地址:https://www.cnblogs.com/flyfish/p/321795.html
Copyright © 2020-2023  润新知