|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
我认为,可以通过更加简单的首次编译,而增加第二次编译的负担,来提高java的运行效率。只是将java源代码进行简单的等价转换,而不假设编译成某种虚拟机器的目标格式,而由本地编译器针对性的二次编译。 在.NET1.1中,我们都晓得可使用app.config大概web.config(ASP.NET)来保留一些设置。但是关于年夜多半人来讲,大概用的最多的只是把它看成一个复杂的ini文件来存储key-value键值对,好比数据库链接字符串,上传文件路径之类的。可是实践上设置文件里能够寄存恣意庞大的布局。假如读过DNN,.Text之类程序的代码,就能够找到这些使用的典范。不外这些项目标代码一样平常都对照冗杂,因而这里我分离.Text的设置办法,对设置文件的用法来做一个复杂的小结。
1、最复杂的写法,只用到appSettings元素。
appSettings里的设定在ConfigurationSettings类里有默许的属性来会见,他前往的是一个NameValueCollection子类的实例。以是一般复杂的字符串值能够保留在这里。写法以下:
<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
<!--最复杂的,在appSettings内里写-->
<appSettings>
<!--界说两个键值-->
<addkey="key1"value="123"/>
<addkey="key2"value="456"/>
</appSettings>
</configuration>
读取的代码:
stringkey1=ConfigurationSettings.AppSettings["key1"];
stringkey2=ConfigurationSettings.AppSettings["key2"];
2、略微加点料。。
appSettings中不单单能够用add来增加键值,还能够用clear或remove元素。
clear的意义是,往除父条理的设置文件中界说的一切键值。
所谓“父条理”的意义是,好比我们在ASP.NET中,当我们用ConfigurationSettings.AppSettings[key]往读取一个值的时分,起首会往反省machine.config里是不是有此键值的设置,然后再往读取web.config.别的,假如在分歧的目次条理中设置web.config,则子目次中web.config的设置会掩盖父目次中的设置。那末这里machine.config相对以后的web.config,大概父目次的config文件相对子目次的config文件,就是一个父子条理的干系。
remove则能够移除一个父条理中设定的键值。
到场这两种语法后的设置文件以下:
<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
<!--最复杂的,在appSettings内里写-->
<appSettings>
<!--这个命令能够删除更高条理中已界说的一切设置-->
<clear/>
<!--这个命令删除一个设置-->
<removekey="somekey"/>
<!--增加设置-->
<addkey="key1"value="123"/>
<addkey="key2"value="456"/>
</appSettings>
</configuration>
(注:remove和clear一样合用于上面将要提到的section和sectionGroup界说的元素傍边能够用add的中央,不再逐一论述)
3、节处置器(SectionHandlers)
在设置文件里除appSettings,还能够自已写XML格局的设置元素,这些元素叫做节(Section)。固然,假如你本人写一堆庞大的XML格局的标签,.NET本身是不晓得怎样剖析的,因而这里就必要你在指定节的同时,告知.NET怎样处置它们,也就是界说“节处置器”(SectionHandlers)。
每个自界说的节,都必要在configSections上面界说它们的节处置器。先来看一个例子:
<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
<!--这个内里用来界说节处置器-->
<configSections>
<sectionname="dicValues"type="System.Configuration.DictionarySectionHandler"/>
</configSections>
<!--这是一个自界说的节-->
<dicValues>
<addkey="key1"value="abc"/>
<addkey="key2"value="def"/>
</dicValues>
</configuration>
这里界说的节利用的是.NETFramework里已有的一个类:DictionarySectionHandler.
由于这些自界说的SectionHandler都要供应给ConfigurationSettings类利用,因而它们都要完成IConfigurationSectionHandler接口。(详细缘故原由能够用Reflector检察ConfigurationSettings的GetConfig办法,一起追踪下往便可找到谜底)。
关于一些罕见情势的数据,体系外部界说了几种handler,其用法具体叙说以下:
1.DictionarySectionHandler
这个范例的handler的GetConfig办法前往一个Hashtable范例的工具。设置办法见下面一个xml.我们能够如许写代码来会见个中的设定:
objecto=ConfigurationSettings.GetConfig("dicValues");
Hashtableht=(Hashtable)o;
foreach(stringkeyinht.Keys)
{
MessageBox.Show(key+"="+ht[key]);
}
2.NameValueSectionHandler
config文件里设定的办法跟DictionarySectionHandler相似:
<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
<configSections>
<sectionname="nameValues"type="System.Configuration.NameValueSectionHandler"/>
</configSections>
<nameValues>
<addkey="key1"value="abc"/>
<addkey="key2"value="def"/>
</nameValues>
</configuration>
可是GetConfig办法前往的是一个NameValueCollection工具:
NameValueCollectionc=(NameValueCollection)ConfigurationSettings.GetConfig("nameValues");
foreach(stringkeyinc.Keys)
{
MessageBox.Show(key+"="+c[key]);
}
3.SingleTagSectionHandler
这类范例的元素体现为一个复杂元素,只要属性而没有子节点。各个属性的值,将会在读取时存到一个Hashtable中前往。设置文件以下:
<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
<configSections>
<sectionname="singleTag"type="System.Configuration.SingleTagSectionHandler"/>
</configSections>
<singleTaga="hello"b="ok"c="haha"/>
</configuration>
读取:
Hashtableht=(Hashtable)ConfigurationSettings.GetConfig("singleTag");
foreach(stringkeyinht.Keys)
{
MessageBox.Show(key+"="+ht[key]);
}
4.IgnoreSectionHandler
偶然候必要界说一些元素,禁绝备由ConfigurationSettings类来处置,而是在内部处置。这时候候为了不发生非常,用这个Handler来声明,可让ConfigurationSettings类读取的时分疏忽该元素。这个用得对照少。
5.自界说节处置器
经由过程完成IConfigurationSectionHandler接口,我们能够完成本人的SectionHandler,在个中保留庞大的设定信息。最多见的是分离序列化来利用。
好比我们必要在设置文件里保留以下信息:
<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
<!--设置节界说部分-->
<configSections>
<!--指定一个叫做StudentSettings的元素,其处置程序是ConfigDemos.Config1.StudentSettingsSectionHandler.
注重:这些程序都必需承继自IConfigurationSectionHandler接口。
这个元素还能够有两个属性:allowDefinition,allowLocation,其寄义本人看msdn.
-->
<sectionname="StudentSettings"type="Config1.StudentSettingsSectionHandler,Config1"/>
</configSections>
<!--实践的数据部分-->
<StudentSettings>
<students>
<Student>
<name>张三</name>
<age>20</age>
</Student>
<Student>
<name>李四</name>
<age>30</age>
</Student>
</students>
</StudentSettings>
</configuration>
我们要在个中保留一组先生的信息,每个先生着名字,岁数等信息。起首我们完成先生类,和响应的settings类:
namespaceConfig1
{
usingSystem;
usingSystem.Xml.Serialization;
[Serializable]
publicclassStudent
{
privatestringname;
privateintage;
//暗示要将此属性序列化为一个元素,而不是属性
[XmlElement("name",typeof(string))]
publicstringName
{
get{returnname;}
set{name=value;}
}
//意义同上
[XmlElement("age",typeof(int))]
publicintAge
{
get{returnage;}
set{age=value;}
}
}
[Serializable]
publicclassStudentSettings
{
privateStudent[]students;
//这个attribute唆使该属性序列化为xml的时分,以多个子元素的情势体现
[XmlArray("students")]
publicStudent[]Students
{
get{returnstudents;}
set{students=value;}
}
}
}
接着我们完成一个节处置器以下,这个类名字和config里界说的是对应的:
namespaceConfig1
{
usingSystem.Configuration;
usingSystem.Xml;
usingSystem.Xml.Serialization;
publicclassStudentSettingsSectionHandler:IConfigurationSectionHandler
{
#regionIConfigurationSectionHandler接口的完成
publicobjectCreate(objectparent,objectconfigContext,XmlNodesection)
{
XmlSerializerser=newXmlSerializer(typeof(StudentSettings));
objectstudents=ser.Deserialize(newXmlNodeReader(section));
returnstudents;
}
#endregion
}
}
好了,我们如今能够用上面的代码来读取设置了。
objecto=ConfigurationSettings.GetConfig("StudentSettings");
StudentSettingssettings=(StudentSettings)o;
for(inti=0;i<settings.Students.Length;i++)
{
Studentstudent=settings.Students;
MessageBox.Show(student.Name+","+student.Age);
}
以上的完成固然对照可行,可是思索到序列化是一个很广泛的操纵,而我们在StudentSettingsSectionHandler类的Create办法里,写逝世了StudentSettings这个范例。这里明显有一种不克不及重用的badsmell,好比我如今必要序列化另外一个设定范例的实例,岂不是又要从头写一个如许的类?
办理这个的举措是让设置类的范例变得能够设置,这个实在在.Text中已有了一个很好的完成了,看一下代码:
namespaceDottext.Framework.Util
{
usingSystem;
usingSystem.Configuration;
usingSystem.Xml;
usingSystem.Xml.Serialization;
usingSystem.Xml.XPath;
publicclassXmlSerializerSectionHandler:IConfigurationSectionHandler
{
publicobjectCreate(objectparent,objectconfigContext,XmlNodesection)
{
XPathNavigatornav=section.CreateNavigator();
stringtypename=(string)nav.Evaluate("string(@type)");
Typet=Type.GetType(typename);
XmlSerializerser=newXmlSerializer(t);
returnser.Deserialize(newXmlNodeReader(section));
}
}
}
这个代码里读取了以后节点的type属性,用反射的体例来创立范例。响应的设置文件里如许写就能够了:
<BlogConfigurationSettingstype="Dottext.Framework.Configuration.BlogConfigurationSettings,Dottext.Framework">
<!--内容省略。。。-->
</BlogConfigurationSettings>
关于庞大范例的设置,实在其实不限于接纳序列化的手腕来保留类的成员。也能够用手工剖析XML里子节点的体例来手工创立设置类的实例。DNN3.2.2中就是这么做的。不外我团体以为这个体例比升引序列化来讲要贫苦一些。代码的复用性和笼统条理也不如.Text这类做法高。
4、sectionGroup
下面先容了怎样利用section来设置节点的处置体例。实在我们还能够用sectionGroup,望文生义sectionGroup就是一组section的组合,并且这个布局是能够恣意嵌套的。这个的用法实在很复杂,这里不再罗嗦。我作了一个嵌套的复杂例子以下:
<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroupname="neilSettings">
<sectionGroupname="s1">
<sectionname="s1a"type="System.Configuration.SingleTagSectionHandler"/>
<sectionname="s1b"type="System.Configuration.NameValueSectionHandler"/>
</sectionGroup>
<sectionname="s2"type="System.Configuration.SingleTagSectionHandler"/>
</sectionGroup>
</configSections>
<neilSettings>
<s1>
<s1am="x"></s1a>
<s1b>
<addkey="name"value="zhangsan"/>
<addkey="age"value="20"/>
</s1b>
</s1>
<s2a="1"b="2"c="3"></s2>
</neilSettings>
</configuration>
要读取这个设置,我们这么写就能够了:
Hashtables1a=(Hashtable)ConfigurationSettings.GetConfig("neilSettings/s1/s1a");
MessageBox.Show(s1a.Count.ToString());//1
NameValueCollections1b=(NameValueCollection)ConfigurationSettings.GetConfig("neilSettings/s1/s1b");
MessageBox.Show(s1b.Count.ToString());//2
Hashtables2=(Hashtable)ConfigurationSettings.GetConfig("neilSettings/s2");
MessageBox.Show(s2.Count.ToString());//3
注重在GetConfig办法中,我们只需传进准确的XPath语法以找出所需节点就能够了。
除用程序本身的config文件来存储设置,我们还能够本人来完成可读写的设置文件,存储庞大的设置。在这方面,ASP.NET1.1的StarterKit中有一个很好的完成,其次要道理是使用了强范例DataSet的一些功效。那样完成有一个优点,就是在VS.NET计划器里有很好的撑持。可视化水平对照高。下一次我会具体来剖析ASP.NET1.1StarterKit的设置完成道理。
以前很热炒跨平台,主要是由于硅谷挑战微软霸主地位的热情,但是冷静下来后,跨平台往往不是那么一回事。假设你有个软件,所谓的跨平台,你只需要为第二个平台上重新编译一次就行了,这样很难么? |
|