• 利用XML序列化实现程序配置文件


      有些应用程序在退出的时候,会将一些设置值写入到文件里,以便下次程序启动时调用,这个文件统称为配置文件。例如:Windows的扫雷程序,在每次启动的时候,都会出现在上次关闭的位置,就是因为扫雷程序在退出的时候将当前位置写入到配置文件里。

      早期的配置文件的实现有两种方法。一是INI文件,在Win32的API中还专门有读写INI文件的API函数;另一个是注册表,这也是很多程 序的首选,在版本较新的扫雷程序就是利用注册表实现配置函数。不过,上述的两种方法都有其的局限性。INI文件,结构简单,容易编辑,有容量的上限 (64K)。注册表虽然没有容量的限制,不过读写注册表还是一件很麻烦的事,而且还容易在注册表中产生冗余(删除程序的时候还得操作注册表),也有和其他 程序想冲的可能。最主要的问题就是,无论是INI文件还是注册表都只能实现简单的配置读写,很难实现类似对象的读写,因为他们的条目之间是平行的,而不是 类似树状的节点结构(注册表虽能实现树状结构,但是读写还是比较麻烦,也不太安全)。

      而利用XML文件就能很好的弥补上面的不足。首先是文件型的,不会读写注册表,不会有安全的后顾之忧;其次没有文件容量大小的限制,而且XML 文件天生是树状结构,很适合实现对象的读写。目前XML文件的应用越来越广泛,已经成为主流,你随便打开一个程序所在的目录,很少不看到XML文件的,而 且主流的开发软件都有读写XML的库文件。操作XML文件现在是很便利的一件事。

      XML文件序列化是XML技术的一个分支,他可以把程序中的一个对象(例如自己编写的类的一个实例)序列化成XML文件。他也可以把XML文件反序列化为程序中的一个对象。

      有关XML序列化比较好的文章,我个人感觉下面这篇比较好。

      NET对象的XML序列化和反序列化

      这就给了我们的一个思路,我们可以把要读写的配置封装在自己编写的配置类中,然后通过XML序列化,来实现配置类和XML文件的转化。

      例如:下面这个例子就是利用XML序列化在类对象和XML之间转换,用的是C#

      下面例子中的xml schema 描述了一个简单的人力资源信息,其中包含了xml的大部分格式,如xml 元素相互嵌套, xml元素既有元素值,又有属性值。

      1. 待序列化的类层次结构
      [XmlRoot("humanResource")]public class HumanResource
        {
          private int m_record = 0;
          private Worker[] m_workers = null;
          [XmlAttribute(AttributeName="record")]public int Record
            {
              get { return m_record; }
              set { m_record = value;

            }
     
          [XmlElement(ElementName="worker")]public Worker[] Workers

            {
              get { return m_workers; }
              set { m_workers = value; }

            }
        }

      public class Worker
        {

          private string m_number = null;

          private InformationItem[] m_infoItems = null;
          [XmlAttribute("number")]public string Number
            {

              get { return m_number; }
              set { m_number = value; }
            }
     
          [XmlElement("infoItem")]public InformationItem[] InfoItems
            {
              get { return m_infoItems; }

              set { m_infoItems = value; }

            }
        }

      public class InformationItem

        {

          private string m_name = null;

          private string m_value = null;

          [XmlAttribute(AttributeName = "name")]public string Name

            {

              get { return m_name; }

              set { m_name = value; }

            }
           [XmlText]public string Value
            {

              get { return m_value; }

              set { m_value = value; }

            }
        }

      2. 序列化生成的xml结构
      <?xml version="1.0" ?>
      <humanResource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance " xmlns:xsd="http://www.w3.org/2001/XMLSchema " record="2">

        <worker number="001">

          <infoItem name="name">Michale</infoItem>

          <infoItem name="sex">male</infoItem>

          <infoItem name="age">25</infoItem>

        </worker>
        <worker number="002">

          <infoItem name="name">Surce</infoItem>

          <infoItem name="sex">male</infoItem>

          <infoItem name="age">28</infoItem>

        </worker>

      </humanResource>

      由于几乎每个程序都会有读写配置文件的操作。那么把XML的序列化和反序列化的操作封装在一个独立的类中,以供用的时候调用。下面是这个类的代码,用的是VB2005

      Imports System
      Imports System.Xml
      Imports System.Xml.Serialization
      Imports System.Text

      '引用合适的命名空间

      Public Interface I_Settings
        Sub InitSettings()
        Function [GetType]() As Type
      End Interface

      '定义一个接口,将XML文件转化为实现这个接口的对象。

     

      Public Class clsXmlSettings

        Public Sub LoadSettings(ByVal Filename As String , ByRef Settings As I_Settings )

          'Settings由于是实现接口的对象,则限定词一定得是ByRef,否则反序列化后,又恢复为初始值
          If My .Computer.FileSystem.FileExists(Filename) = False Then Exit Sub
          If Settings Is Nothing Then Exit Sub

          Settings.InitSettings()

          Dim tB() As Byte = My .Computer.FileSystem.ReadAllBytes(Filename)
          Dim tS As IO.Stream = New IO.MemoryStream(tB)
          Dim XS As New XmlSerializer(Settings.GetType)

          Settings = XS.Deserialize(tS)
        End Sub

        Public Sub SaveSettings(ByVal FileName As String , ByRef Settings As I_Settings)
          If Settings Is Nothing Then Exit Sub

          Dim tS As New IO.MemoryStream
          Dim XS As New XmlSerializer(Settings.GetType)
          XS.Serialize(tS, Settings)

          Dim tB() As Byte = tS.ToArray

          My .Computer.FileSystem.WriteAllBytes(FileName, tB, False)
        End Sub

      End Class

      实现I_Settings接口的对象,必须实现两个方法。InitSettings为初始化类中的属性值。如果XML中没有对应的设置时,类相应的值就用原来的初始值。GetType方法返回对象的Type属性,只要在方法中加一句话就行了:

      Return Me .GetType

      但也意味着,在反序列化的时候必须先实例化对象。

      通过以上的类,封装了XML序列化和反序列化。任何实现I_Settings的类,都能和相应的XML文件互相转化。也就实现了本文的利用XML序列化实现程序配置文件的思路。

    转自 :http://grenet.cnblogs.com/

  • 相关阅读:
    Mysql源代码分析系列(2): 源代码结构转载
    Python 元组、列表、字典、文件
    Mysql源代码分析系列(1): 编译和调试转载
    ETL测试参考文档
    MySql select into与set的区别
    STL container
    mysqlclient5.0.2614 RPM for ppc
    linux多线程的总结(pthread用法)
    给线程变量pthread_t *thread动态分配空间
    当SQL数据库日志文件已满,或者日志很大,怎么办
  • 原文地址:https://www.cnblogs.com/hjslovewcl/p/2314349.html
Copyright © 2020-2023  润新知