由于项目的需要,要在C#里操作.ini相关的操作。结合自己现在的学习进度,决定将以后要实现的通用的功能写成类库。在网上寻找相关的资料后就开始动手写,希望以后能把这个类库写成一个有架构的(但愿如此)。一来以后便于总结,而来也可以给别人使用(但愿有人使用^^)。
首先来介绍一下,.ini配置文件。这个一般是在windows程序里使用,还是比较常见的。简单来说,我们可以把它看成一个数据库,分为section,key-value这两级。section是指一个配置集合所在的区域,在这个区域里有许多key-value的配置,key可以看成索引或者关键字,这个关键字的值便是value了。比如学生名字与成绩的一组对应。编辑文件的效果是这样的:
[first]name=haloworld[串口1]波特率=9600奇偶校验=奇校验停止位=1
接下来我们需要调用windows用来处理ini配置文件的API函数。调用Windows的API函数需要用到using System.Runtime.InteropServices命名空间,这个空间下的成员类可以让我们有能力调用Windows中的API函数(一般都包含在kernel32.dll里)。调用格式与说明如下:
using System.Runtime.InteropServices;//调用windows的API#region ##调用windows的API## /// <summary> /// DLL调用读取ini文件API函数 /// </summary> /// <param name="section">要读取的段落</param> /// <param name="key">要读取值的键</param> /// <param name="defVal">读取异常情况下的缺省值</param> /// <param name="retVal">key(键值对应的值),若不存在则返回空值</param> /// <param name="size">该值所允许的大小</param> /// <param name="filePath">ini文件的完整路径名称</param> /// <returns>返回值类型</returns> [DllImport("kernel32")] private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath); /// <summary> /// DLL调用写入ini文件API函数 /// </summary> /// <param name="section">要写入的段落</param> /// <param name="key">要写入的值的键</param> /// <param name="val">key所对应的值</param> /// <param name="filePath">ini文件的完整路径名称</param> /// <returns>返回值类型</returns> [DllImport("kernel32")] private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); #endregion
然后就可以写类了,这里的功能比较少,提供了三个公共变量,并进行异常处理,代码如下:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;using System.Runtime.InteropServices;namespace halo_class_lib{ public class iniFile { #region ##调用windows的API## /// <summary> /// DLL调用读取ini文件API函数 /// </summary> /// <param name="section">要读取的段落</param> /// <param name="key">要读取值的键</param> /// <param name="defVal">读取异常情况下的缺省值</param> /// <param name="retVal">key(键值对应的值),若不存在则返回空值</param> /// <param name="size">该值所允许的大小</param> /// <param name="filePath">ini文件的完整路径名称</param> /// <returns>返回值类型</returns> [DllImport("kernel32")] private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath); /// <summary> /// DLL调用写入ini文件API函数 /// </summary> /// <param name="section">要写入的段落</param> /// <param name="key">要写入的值的键</param> /// <param name="val">key所对应的值</param> /// <param name="filePath">ini文件的完整路径名称</param> /// <returns>返回值类型</returns> [DllImport("kernel32")] private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); #endregion #region ##变量声明## private string _iniPath = "C:/default.ini";//配置文件路径,默认使用C盘根目录 private string _deVal = "null"; //读取异常情况的缺省值 private int _bufferSize = 255; //缓存大小 public string iniPath { set { _iniPath = value; } get { return _iniPath; } } public string deVal { set { _deVal = value; } get { return _deVal; } } public int bufferSize { set {_bufferSize = value;} get {return _bufferSize;} } #endregion #region ## 公共函数 ## public iniFile(string Path, int Size, string DeVal) { _iniPath = Path; _bufferSize = Size; _deVal = DeVal; } public iniFile(string Path) { _iniPath = Path; } /// <summary> /// 读配置函数 /// </summary> /// <param name="section">要读取的段落</param> /// <param name="key">要读取的值的键</param> /// <param name="path">配置文件路径</param> /// <returns>返回读取值</returns> public string readIniValue(string section, string key , string path = null) { if (path != null) { this._iniPath = path; } StringBuilder temp = new StringBuilder(_bufferSize); if (File.Exists(this._iniPath)) { try { GetPrivateProfileString(section, key, this._deVal, temp, this._bufferSize, this._iniPath); } catch (System.Exception ex) { throw ex;//在类中不宜使用对话框、打印输出等手段,还是抛出比较好 } return temp.ToString(); } else return "the path don't exsist!"; } /// <summary> /// 写配置文件函数 /// </summary> /// <param name="section">要写入的段落</param> /// <param name="key">要写入值的键</param> /// <param name="keyValue">要写入的值</param> /// <param name="path">配置文件的路径</param> /// <returns>true-成功;false-失败</returns> public bool writeIniValue(string section, string key, string keyValue, string path = null)//若不存在配置文件,需要创建 { if (path != null) { this._iniPath = path; } if (!File.Exists(this._iniPath)) { using (StreamWriter sw = File.CreateText(this._iniPath)) { sw.Close(); } } try { WritePrivateProfileString(section, key, keyValue, this.iniPath); } catch (System.Exception ex) { return false; throw ex; } return true; } #endregion }}
写好类之后先简单进行一下测试(就两个功能,就测试一下读写就行),代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using halo_class_lib; 6 7 namespace test22 8 { 9 class Program10 {11 static void Main(string[] args)12 {13 iniFile my = new iniFile("D:/HALO.ini", 255, "#");14 my.writeIniValue("串口1", "波特率", "9600");15 my.writeIniValue("串口1", "奇偶校验", "奇校验");16 my.writeIniValue("串口1", "停止位", "1");17 18 //string her = my.readIniValue("first", "name");19 //System.Console.WriteLine(her);20 21 //System.Console.Read();22 }23 }24 }
经过测试,功能还算正常。虽然比较简单,不过也算是走了一遍流程,以后编写好代码一定要养成将代码抽象成基础的类库,这个类就是起点(PS:写博客还真是锻炼人的组织能力。。)
参考:http://www.cnblogs.com/gaohades/archive/2006/01/24/322751.html