织梦CMS - 轻松建站从此开始!

罗索

当前位置: 主页>杂项技术>.NET(C#)>

在.NET中读写INI文件 ——兼谈正则表达式的应用

落鹤生 发布于 2010-05-26 21:38 点击:次 
本文着重演示了正则表达式在读写INI文件时的应用。所实现的INI文件读写类FileIni扩展性稍显不足,例如,这个类只能处理通用格式的INI文件,对于格式稍有变化的INI文件,此类中的正则表达式就需要修改了。总之,正则表达式是处理字符串的强大工具,掌握了它对我们更高效
TAG:

INI文件是Windows平台上的一种较常用的软件配置文件格式,Windows应用程序常常使用它来保存一些配置信息。它一般是由数个包含key-value对的Section组成,每个key-value对保存着一些软件配置信息。例如最典型的NT系列的启动配置文件boot.ini:
--------------------------------------------------------------------------------

[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(2)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Microsoft Windows XP Professional" /fastdetect
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /fastdetect

--------------------------------------------------------------------------------
在这个文件中,方括号中的字符串是Section的名字,两个方括号之间的内容为一个Section。Section的内容是一些key-value对,每个key-value对占据一行,例如timeout=30就是一对key-value对,timeout是key,对应的value是30。Windows平台专门提供了一组API可以方便地操作INI文件,例如GetPrivateProfileSection()、GetPrivateProfileInt()等。

随着Windows系列操作系统的不断发展,INI文件的作用逐渐被注册表、XML格式的config文件等所取代,很少再用于系统配置,但我们仍可以在应用程序中使用它。在.NET平台上推荐使用的软件配置文件格式是基于XML的config文件,因此在.NET Framework中并没有提供对INI文件读写的特殊支持,使得我们有时在需要读写INI文件时不是很方便。本文将探讨如何使INI文件的读写在.NET平台上变得更加容易。当然,我们可以直接引入上述的API,但本文将不使用API,而是完全基于.NET Framework。

创建INI文件读写类 

要在.NET平台上处理INI文件,很自然的想法就是创建一个专门的class来负责INI文件的读写工作,这个class暴露适当的接口供外部调用。一般的INI文件的尺寸很小,因此最简单的做法就是以文本的方式将整个文件读入一个string变量中。类定义如下:

  1. public class FileIni 
  2. private string fileContents = null
  3. public FileIni(string fileName) 
  4. if(File.Exists(fileName)) 
  5. StreamReader r = File.OpenText(fileName); 
  6. fileContents = r.ReadToEnd(); 
  7. r.Close(); 

接下来我们要提供一些方法来操作这个字符串,比如从中返回所有的Section Name、取得特定的key所对应的value等。我们可以使用字符串查找之类的方法来完成这些工作,但是.NET Framework为我们提供了更好的方法,那就是正则表达式。

正则表达式

所谓正则表达式是一种被设计用来优化字符串操作的语言。它使用一组元字符(Metacharacters)来实现强劲的字符串操作能力。这组元字符最早来自于对DOS文件系统中?和*的扩展。在DOS文件系统中,?和*分别被用来代替单个字符和字符群组,它们可以被认为是最早的元字符。正则表达式在它们的基础上不断扩充,形成了一套元字符集,能够表达非常复杂的字符串。

举例来说,网上注册时常常需要用户输入一个有效的Email地址。当用户输入一个字符串后,我们如何验证这个Email地址是否合法呢?使用下面这个正则表达式可以轻易地实现目的:
-------------------------------------------------------------------------------- 

@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"

--------------------------------------------------------------------------------
关于这个正则比表达式的含义,在此不做过多解释,有兴趣的朋友可以参考相关的正则表达式资料。这个正则表达式虽不能保证用户输入的Email地址100%的真实有效,但至少可以保证用户输入的Email地址看上去是合法有效的。

.NET Framework中提供了一些使用正则表达式的类,这些类位于System.Text.RegularExpressions名字空间下。

使用正则表达式实现FileIni类的功能 

现在我们可以使用正则表达式来实现FileIni类的相应功能了。为了返回INI文件中所有Section的名字,我们可以使用一个只读属性SectionNames来返回一个Section Name的字符串数组。

  1. public string[] SectionNames 
  2. get 
  3. // Using regular expression to get all section names. 
  4. string regexPattern = @"\[(?<SectionName>\w*)\]"
  5. Regex r = new Regex(regexPattern);  // Match "[anywords]" 
  6. MatchCollection matches = r.Matches(fileContents); 
  7. // Writing all section names to a string array. 
  8. string[] results = new string[matches.Count]; 
  9. for(int i = 0; i < matches.Count; i++) 
  10.     results[i] = matches[i].Result("${SectionName}"); 
  11. return results; 

在上面的代码中,我们使用一个正则表达式:@"\[(?<SectionName>\w*)\]",对源字符串进行一次匹配就取出了所有的Section Name。

为了取得特定Section下的特定的key的value,我们先要取得此Section下的所有内容,然后再从中取出特定key的value。

  1. public string GetSectionString(string sectionName) 
  2.     string regexPattern = @"(\[" + sectionName + @"\]" 
  3. + @"(?<SectionString>.*)\[)"
  4.     Regex r = new Regex(regexPattern, RegexOptions.Singleline); 
  5.     if(r.IsMatch(fileContents)) 
  6.     { 
  7.     return r.Match(fileContents).Result("${SectionString}"); 
  8.     } 
  9.     return string.Empty; 

GetSectionString()根据特定的sectionName取得此Section的全部内容。假设sectionName为字符串boot loader,此时的正则表达式为@”(\[boot loader\](?<SetionString>.*)\[]”。得到Section下的所有内容后,我们再从其中得到我们想要的value值。

  1. public string GetKeyString(string sectionName, string keyName) 
  2.     string sectionString = this.GetSectionString(sectionName); 
  3.     string regexPattern = @"(" + keyName + @"=(?<value>.*)\r\n)"
  4.     Regex r = new Regex(regexPattern); 
  5.     if(r.IsMatch(fileContents)) 
  6.     { 
  7.     return r.Match(fileContents).Result("${value}"); 
  8.     } 
  9.     return string.Empty; 

在此基础上,可以得到更多的诸如GetKeyInt()之类的方法。至于写方法,利用Regex的Replace()方法也是很容易实现的,在此就不做过多的叙述了。

总结

本文着重演示了正则表达式在读写INI文件时的应用。所实现的INI文件读写类FileIni扩展性稍显不足,例如,这个类只能处理通用格式的INI文件,对于格式稍有变化的INI文件,此类中的正则表达式就需要修改了。总之,正则表达式是处理字符串的强大工具,掌握了它对我们更高效地处理字符串是绝对有好处的。

(wiseman)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201005/9512.html]
本文出处:博客园 作者:wiseman
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容