c#中配置文件的使用(一)

来源:互联网 发布:天刀男性捏脸数据 编辑:程序博客网 时间:2024/05/10 14:41

     在使用log4net的时候,需要自己来配置相关的文件,之前虽然研究过如何来使用配置文件,但是时间一久还是有点生疏,下面自己做的一些小test,也让自己能够有比较深的印象,在学习过程中,也在网上看到了一位大神写的相关的内容,比较详细,这是大神博客关于配置文件的地址http://www.cnblogs.com/kissdodog/archive/2013/04/11/3014227.html,然后根据这个我自己做了一些尝试,并写出自己的理解和体会。

    在vs中,创建一个项目,然后就会生成一个app.config的配置文件,可以在这个配置文件中设置,当然也可以自己写配置文件,然后自己去封装一下,模仿app.config的各项功能实现方法即可,下面的test都是在app.config文件中实现的。

   1. 直接使用appsettings和connectionStrings节,如果是不太复杂的配置文件,使用这2个节就够用了,下面是一个简单的例子

  

<?xml version="1.0" encoding="utf-8" ?><configuration>  <appSettings>    <add key="User1" value="password1"/>    <add key="User2" value="password2"/>    <add key="User3" value="password3"/>  </appSettings>  <connectionStrings>    <add name ="sqlite" connectionString ="dataSource = /数据库/db"/>  </connectionStrings>    </configuration>

上面的配置文件的写法还是比较好理解的,我需要3个配置项User1,User2,User3,其对应的value分别为password1,password2,password3,在下面的代码中,可以很简单的就能读取出来上面所写的配置项。

public void Test1()        {            var password1 = ConfigurationManager.AppSettings["User1"];            var password2 = ConfigurationManager.AppSettings["User2"];            var password3 = ConfigurationManager.AppSettings["User3"];            Console.WriteLine(password1 + '\n' + password2 + '\n' + password3 + '\n');            var connectionString = ConfigurationManager.ConnectionStrings["sqlite"];            Console.WriteLine(connectionString);        }

上面的程序运行的代码结果,就是显示了对应的配置项的value,这样就可以用于在刚打开程序的时候,对某些变量进行赋值了。

2. 有时会在程序中对配置文件进行修改,可以按照下面的方法来

static void Main(string[] args)        {            Configuration cfa = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); //首先打开配置文件            cfa.AppSettings.Settings.Add("User4", "password4");  //向配置文件中添加一个新的项            cfa.AppSettings.Settings["User1"].Value = "password5";//修改配置文件中的某一个项的value            cfa.Save();  //保存配置文件            ConfigurationManager.RefreshSection("appSettings");  //刷新配置文件        }
在调试上面代码的时候发现,app.config没有发生变化,但是在生成的应用程序里面打开的时候,发现config文件是发生 了变化的,之前在查找相关信息的时候,网上很多都说这样修改是不对的,是无法实现的,所以很多就用xml方面的操作方法来进行了修改(这个在后面的学习中会做一个总结)。

但是其实原因在于:在我们调试的时候,编译器会把debug下的exe,dll,config给覆盖掉。执行代码时候,其实是将debug目录下的config内容改变。而项目下的app.config文件并没有改变。。。所以再次进行调试的时候debug下的config又被项目下的app.config覆盖。

3. vs自带的handler可以用来自定义一些配置节

<?xml version="1.0" encoding="utf-8" ?><configuration>  <configSections> <!--这个节其实就是用来设置下面的自定义节的名字和相关的类型-->    <section name="UserName" type="System.Configuration.NameValueSectionHandler"/>  <!--返回Name Value类型形式的节-->    <section name="UserAge" type="System.Configuration.DictionarySectionHandler"/> <!--返回字典类型形式的节-->    <section name="UserHeight" type="System.Configuration.SingleTagSectionHandler"/> <!--基础结构。处理 .config 文件中由单个 XML 标记所表示的各配置节。-->  </configSections>    <UserName>    <add key="1" value="王二"/>    <add key="2" value="张三"/>    <add key="3" value="李四"/>  </UserName>    <UserAge>    <add key="1" value="23"/>    <add key="2" value="24"/>    <add key="3" value="25"/>  </UserAge>    <UserHeight one="170" two="180" three="190"/>      <startup>         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />    </startup></configuration>  

上面自定了三个节,类型分别为NameValue的表示形式,dictionary的表示形式,还有个是最基础的结构,类似于appsettings节,写上相应的配置信息,然后就可以调用了

public static void Test2()        {            var section1 = (NameValueCollection)ConfigurationManager.GetSection("UserName");  //首先要获取对应的配置节            var name1 = section1["1"];  //这边也可以使用section1.Allkeys来遍历,这边是为了说明如果知道key的值,可以直接获得对应的Value值            var name2 = section1["2"];            var name3 = section1["3"];            Console.WriteLine(name1 + "," + name2 + "," + name3);            var section2 = (IDictionary) ConfigurationManager.GetSection("UserAge");            foreach (var key in section2.Keys)  //这边因为是字典,因此遍历是使用keys,跟上面的Allkeys不一样。            {                Console.WriteLine(section2[key]);            }            var section3 = (IDictionary) ConfigurationManager.GetSection("UserHeight");            foreach (var key in section3.Keys)            {                Console.WriteLine(section3[key]);            }        }

通过上面的例子可以知道,通过系统提供的handler,除了这3个还有很多,我们可以自己来创建一些配置节,并且设置节的属性,这样可以更好的把不同功能或者不同类型的配置信息区分开来。另外根据自己的需要选择不同的handler,这样在应用配置文件的时候也能根据需要更简单的获得自己想要的信息。

4. 如果觉得系统的handler不能满足自己的要求,这时候可以自定义handler

<?xml version="1.0" encoding="utf-8" ?><configuration>  <configSections>    <section name="Person" type="Test2.PersonHandler,Test2"/> <!--type后面第一个参数是该节定义的位置,第二个参数是该节所在的程序集-->  </configSections>  <Person age="25" name="User1"/>  <!--Person中使用2个hashtable,第一层key是Person,后面的内容是value.第二层key是age和name,值是value-->    <startup>         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />    </startup></configuration>

具体的使用代码如下,其实跟使用系统自带的handler使用方法类似,通俗点说就跟压缩软件一样的就是怎么压缩的,使用同样的方法再解压缩得到想要的值就可以了

class Program    {        static void Main(string[] args)        {            Hashtable section = ConfigurationManager.GetSection("Person") as Hashtable; //跟上面一样获取section,不过这个section是hashtable类型的。            if (section != null)                foreach (DictionaryEntry key in section)      //第一层table                {                    Hashtable attrs = (Hashtable) key.Value; //根据key,来获取对应的value,而这个value又是第2层hashtable                    foreach (DictionaryEntry attr in attrs)                    {                        Console.WriteLine(attr.Key);    //解析第2层hashtable就可以得到配置文件中Person节中的信息了。                        Console.WriteLine(attr.Value);                    }                }        }    }    class PersonHandler : IConfigurationSectionHandler    {        public object Create(object parent, object configContext, XmlNode section)        {            Hashtable configSection = new Hashtable();            Hashtable configAttribute = new Hashtable();            if (section.Attributes != null)            {                foreach (XmlAttribute attribute in section.Attributes)                {                    if (attribute.NodeType == XmlNodeType.Attribute)                    {                        configAttribute.Add(attribute.Name, attribute.Value);                    }                }            }            configSection.Add(section.Name, configAttribute);            return configSection;            }    }