2013年2月24日星期日

c#软件配置文件读写方式总结(一)


网址: http://www.cnphp.info/csharp-application-config-methods-part1.html
一般在软件与用户的交互过程中,很产生多个参数;这些参数需要在用户关闭软件后保存下来。传统的Windows程序使用ini文件来记录这些参数。
Ini文件的格式

[section1]
Key1=value
Key2=value

[sectionX]
Key3=value
Key4=value

在c#中,我们可以调用这些API来完成自定义用户配置文件的读写;也可以通过分析文本文件的方式来读写。

第一种方式:调用Windows API读写ini文件
在kernel32.dll中有一下几个常用的ini文件的操作函数,下面是它们在c#中封送的格式

        [System.Security.SuppressUnmanagedCodeSecurity]
        private static class NativeMethods{
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer, uint nSize, string lpFileName);
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern uint GetPrivateProfileString(string lpAppName,string lpKeyName, string lpDefault, StringBuilder lpReturnedString,
int nSize, string lpFileName);
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern uint GetPrivateProfileString(string lpAppName,
string lpKeyName, string lpDefault, [In, Out] char[] lpReturnedString,int nSize,
string lpFileName);
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, IntPtr lpReturnedString, uint nSize,string lpFileName);
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetPrivateProfileInt(string lpAppName,string lpKeyName, int lpDefault, string lpFileName);
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern int GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName); }
具体的使用方法笔者也不在这里一一赘述了,感兴趣的朋友可以自行翻阅下API手册。
第二种方式:文本分析读写ini文件
这种方法很常用,读取ini文件后逐行分析,笔者在这里给出加载ini文件的代码。默认将分析结果保存在一个Dictionary>的泛型里。Item是自定义的一个结构变量。

public struct Item
{
    public string Field { get; set; } //键
    public object Value { get; set; }  //值
}

        public void Load(string iniFile)
        {
            // 读取文件,剔除空行和注释行
            var rawFileData =               System.IO.File.ReadAllLines(iniFile).Where(line=> !line.Equals(string.Empty) && !line.StartsWith(";"));
            // 定义一个[section]结
            var currentSection = string.Empty;
            // 读取每行
            foreach (var line in rawFileData)
            {
                // 查找section
                if (line.StartsWith("[")) {
                    currentSection = line.TrimStart('[').TrimEnd(']');
                    if (!SectionExists(currentSection)) Add(currentSection);
                }
                else{
                    // 查找key=value键值对
                    var lineData = line.Split('=');
                    for (var i = 0; i < lineData.Count(); i++)
                        lineData[i] = lineData[i].Trim();
                    // Try some conversions to store the item as their natural format.
                    bool boolTest;
                    decimal numTest;
                    // 分析值的类型为布尔量还是数字量
                    if(Boolean.TryParse(lineData[1], out boolTest)){
                        this[currentSection].Add(new Item { Field = lineData[0], Value = boolTest });
//继续
                        continue;

                    }
                    // 分析数字量
                    if (Decimal.TryParse(lineData[1], out numTest)){
                        this[currentSection].Add(new Item { Field = lineData[0], Value = numTest });
                        // 继续
                        continue;
                    }
                    // 默认为值类型为字符串
                    this[currentSection].Add(new Item { Field = lineData[0], Value = lineData[1] });
                }
            }
        }

没有评论:

发表评论