zoukankan      html  css  js  c++  java
  • C# 操作ini文件

    INI文件是一种按照特点方式排列的文本文件。每一个INI文件构成都非常类似,由若干段落(section)组成,在每个带括号的标题下面,是若干个以单个单词开头的关键词(keyword)和一个等号,等

    号右边的就是关键字对应的值(value)。其一般形式如下:

    1 [section1]
    2  keyword1=value1 
    3  keyword2=value2
    4  keyword3=value3
    5 [section2]
    6  keyword1=value1
    7  keyword2=value2
     1 class Program
     2 
     3     {
     4 
     5         [DllImport("kernel32")]
     6 
     7         private  static extern long WritePrivateProfileString (string section ,string key , string val ,string filepath);
     8 
     9         //参数说明:section:INI文件中的段落;key:INI文件中的关键字;val:INI文件中关键字的数值;filePath:INI文件的完整的路径和名称。
    10 
    11         [DllImport ("kernel32")]
    12 
    13         private static extern int GetPrivateProfileString (string section , string key , string def , StringBuilder retVal , int size , string filePath ) ;
    14 
    15         //参数说明:section:INI文件中的段落名称;key:INI文件中的关键字;def:无法读取时候时候的缺省数值;retVal:读取数值;size:数值的大小;filePath:INI文件的完整路径和名称。
    16 
    17         public static void Main(string[] args)
    18 
    19         {
    20 
    21             
    22 
    23             string section="database";
    24 
    25             string key="sql";
    26 
    27             //string value="server.;database=pubs;uid=sa;pwd=";
    28 
    29             string fileName="d:\config.ini";
    30 
    31             
    32 
    33             try
    34 
    35             {
    36 
    37                 //写入ini节点
    38 
    39                 //WritePrivateProfileString(section,key,value,fileName);
    40 
    41                 
    42 
    43                 //读取ini节点
    44 
    45                 StringBuilder sb=new StringBuilder(255);
    46 
    47                 GetPrivateProfileString(section,key,"无法读取",sb,255,fileName);
    48 
    49                 
    50 
    51                 Console.WriteLine(sb.ToString());
    52 
    53                 
    54 
    55             }catch(Exception ex)
    56 
    57             {
    58 
    59                 Console.WriteLine(ex.ToString());
    60 
    61             }
    62 
    63             
    64 
    65             Console.Write("Press any key to continue . . . ");
    66 
    67             Console.ReadKey(true);
    68 
    69         }
    70 
    71         
    72 
    73     }

    整理出ini文件操作类:

      1 /// <summary>
      2     /// 读写INI文件的类。
      3     /// </summary>
      4     public class INIHelper
      5     {
      6         // 读写INI文件相关。
      7         [DllImport("kernel32.dll", EntryPoint = "WritePrivateProfileString", CharSet = CharSet.Ansi)]
      8         public static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
      9         [DllImport("kernel32.dll", EntryPoint = "GetPrivateProfileString", CharSet = CharSet.Ansi)]
     10         public static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
     11 
     12         [DllImport("kernel32.dll", EntryPoint = "GetPrivateProfileSectionNames", CharSet = CharSet.Ansi)]
     13         public static extern int GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer, int nSize, string filePath);
     14         
     15         [DllImport("KERNEL32.DLL ", EntryPoint = "GetPrivateProfileSection", CharSet = CharSet.Ansi)]
     16         public static extern int GetPrivateProfileSection(string lpAppName, byte[] lpReturnedString, int nSize, string filePath);
     17 
     18 
     19         /// <summary>
     20         /// 向INI写入数据。
     21         /// </summary>
     22         /// <PARAM name="Section">节点名。</PARAM>
     23         /// <PARAM name="Key">键名。</PARAM>
     24         /// <PARAM name="Value">值名。</PARAM>
     25         public static void Write(string Section, string Key, string Value, string path)
     26         {
     27             WritePrivateProfileString(Section, Key, Value, path);
     28         }
     29 
     30 
     31         /// <summary>
     32         /// 读取INI数据。
     33         /// </summary>
     34         /// <PARAM name="Section">节点名。</PARAM>
     35         /// <PARAM name="Key">键名。</PARAM>
     36         /// <PARAM name="Path">值名。</PARAM>
     37         /// <returns>相应的值。</returns>
     38         public static string Read(string Section, string Key, string path)
     39         {
     40             StringBuilder temp = new StringBuilder(255);
     41             int i = GetPrivateProfileString(Section, Key, "", temp, 255, path);
     42             return temp.ToString();
     43         }
     44 
     45         /// <summary>
     46         /// 读取一个ini里面所有的节
     47         /// </summary>
     48         /// <param name="sections"></param>
     49         /// <param name="path"></param>
     50         /// <returns></returns>
     51         public static int GetAllSectionNames(out string[] sections, string path)
     52         {
     53             int MAX_BUFFER = 32767;
     54             IntPtr pReturnedString = Marshal.AllocCoTaskMem(MAX_BUFFER);
     55             int bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, path);
     56             if (bytesReturned == 0)
     57             {
     58                 sections = null;
     59                 return -1;
     60             }
     61             string local = Marshal.PtrToStringAnsi(pReturnedString, (int)bytesReturned).ToString();
     62             Marshal.FreeCoTaskMem(pReturnedString);
     63             //use of Substring below removes terminating null for split
     64             sections = local.Substring(0, local.Length - 1).Split('');
     65             return 0;
     66         }
     67 
     68         /// <summary>
     69         /// 得到某个节点下面所有的key和value组合
     70         /// </summary>
     71         /// <param name="section"></param>
     72         /// <param name="keys"></param>
     73         /// <param name="values"></param>
     74         /// <param name="path"></param>
     75         /// <returns></returns>
     76         public static int GetAllKeyValues(string section, out string[] keys, out string[] values, string path)
     77         {
     78             byte[] b = new byte[65535];
     79 
     80             GetPrivateProfileSection(section, b, b.Length, path);
     81             string s = System.Text.Encoding.Default.GetString(b);
     82             string[] tmp = s.Split((char)0);
     83             ArrayList result = new ArrayList();
     84             foreach (string r in tmp)
     85             {
     86                 if (r != string.Empty)
     87                     result.Add(r);
     88             }
     89             keys = new string[result.Count];
     90             values = new string[result.Count];
     91             for (int i = 0; i < result.Count; i++)
     92             {
     93                 string[] item = result[i].ToString().Split(new char[] { '=' });
     94                 if (item.Length == 2)
     95                 {
     96                     keys[i] = item[0].Trim();
     97                     values[i] = item[1].Trim();
     98                 }
     99                 else if (item.Length == 1)
    100                 {
    101                     keys[i] = item[0].Trim();
    102                     values[i] = "";
    103                 }
    104                 else if (item.Length == 0)
    105                 {
    106                     keys[i] = "";
    107                     values[i] = "";
    108                 }
    109             }
    110 
    111             return 0;
    112         }
    113 
    114     }

    文件由若干个段落(section)组成,每个段落又分成若干个键(key)和值(value)。Windows系统自带的Win32的API函数GetPrivateProfileString()和WritePrivateProfileString()分别实现了对INI文件的读写操作,他们位于kernel32.dll下。

    但是令人遗憾的是C#所使用的.NET框架下的公共类库并没有提供直接操作INI文件的类,所以唯一比较理想的方法就是调用API函数。

    然后,.Net框架下的类库是基于托管代码的,而API函数是基于非托管代码的,(在运行库的控制下执行的代码称作托管代码。相反,在运行库之外运行的代码称作非托管代码。)如何实现托管代码与非托管代码之间的操作呢?.Net框架的System.Runtime.InteropServices命名空间下提供各种各样支持COM interop及平台调用服务的成员,其中最重要的属性之一DllImportAttribute可以用来定义用于访问非托管API的平台调用方法,它提供了对从非托管DLL导出的函数进行调用所必需的信息。下面就来看一下如何实现C#与API函数的互操作。

    读操作:

    1 [DllImport("kernel32")]
    2 private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath); 
    3 section:要读取的段落名
    4 key: 要读取的键
    5 defVal: 读取异常的情况下的缺省值
    6 retVal: key所对应的值,如果该key不存在则返回空值
    7 size: 值允许的大小
    8 filePath: INI文件的完整路径和文件名

    写操作:

    1 [DllImport("kernel32")] 
    2 private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); 
    3 section: 要写入的段落名
    4 key: 要写入的键,如果该key存在则覆盖写入
    5 val: key所对应的值
    6 filePath: INI文件的完整路径和文件名

    这样,在就可以使用对他们的调用,用常规的方式定义一个名为IniFile类:

    1using System;
     2using System.Runtime.InteropServices; 
     3using System.Text; 
     4
     5namespace IPVOD.Hotel.Remoting
     6{
     7    /// <summary>
     8    /// INI文件的操作类
     9    /// </summary>
    10    public class IniFile
    11    {
    12        public string Path;
    13
    14        public IniFile(string path)
    15        {
    16            this.Path = path;
    17        }
    18        
    19        #region 声明读写INI文件的API函数 
    20        [DllImport("kernel32")] 
    21        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); 
    22
    23        [DllImport("kernel32")]
    24        private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath); 
    25
    26        [DllImport("kernel32")]
    27        private static extern int GetPrivateProfileString(string section, string key, string defVal, Byte[] retVal, int size, string filePath);
    28        #endregion
    29
    30        /// <summary>
    31        /// 写INI文件
    32        /// </summary>
    33        /// <param name="section">段落</param>
    34        /// <param name="key"></param>
    35        /// <param name="iValue"></param>
    36        public void IniWriteValue(string section, string key, string iValue) 
    37        {
    38            WritePrivateProfileString(section, key, iValue, this.Path);
    39        }
    40
    41        /// <summary>
    42        /// 读取INI文件
    43        /// </summary>
    44        /// <param name="section">段落</param>
    45        /// <param name="key"></param>
    46        /// <returns>返回的键值</returns>
    47        public string IniReadValue(string section, string key) 
    48        { 
    49            StringBuilder temp = new StringBuilder(255); 
    50
    51            int i = GetPrivateProfileString(section, key, "", temp, 255, this.Path); 
    52            return temp.ToString();
    53        }
    54
    55        /// <summary>
    56        /// 读取INI文件
    57        /// </summary>
    58        /// <param name="Section">段,格式[]</param>
    59        /// <param name="Key"></param>
    60        /// <returns>返回byte类型的section组或键值组</returns>
    61        public byte[] IniReadValues(string section, string key)
    62        {
    63            byte[] temp = new byte[255];
    64
    65            int i = GetPrivateProfileString(section, key, "", temp, 255, this.Path);
    66            return temp;
    67        }
    68    }
    69}
    70

    注意:我增加了DLL导出的函数GetPrivateProfileString的重载,说明如下:

    1 [DllImport("kernel32")] 
    2 private static extern int GetPrivateProfileString(string section, string key, string defVal, Byte[] retVal, int size, string filePath);
    3 section:要读取的段落名
    4 key: 要读取的键
    5 defVal: 读取异常的情况下的缺省值
    6 retVal: 此参数类型不是string,而是Byte[]用于返回byte类型的section组或键值组。
    7 size: 值允许的大小
    8 filePath: INI文件的完整路径和文件名
     1 下面看一下具体实例化IniFile类的操作:
     2 
     3 //path为ini文件的物理路径
     4 
     5 IniFile ini = new IniFile(path);
     6 
     7 //读取ini文件的所有段落名
     8 
     9 byte[] allSection = ini.IniReadValues(null, null);
    10 
    11  
    12 
    13 通过如下方式转换byte[]类型为string[]数组类型
    14 
    15 string[] sectionList;
    16 
    17 ASCIIEncoding ascii = new ASCIIEncoding();
    18 
    19 //获取自定义设置section中的所有key,byte[]类型
    20 
    21 sectionByte = ini.IniReadValues("personal", null);
    22 
    23 //编码所有key的string类型
    24 
    25 sections = ascii.GetString(sectionByte);
    26 
    27 //获取key的数组
    28 
    29 sectionList = sections.Split(new char[1]{''});
    30 
    31  
    32 
    33 //读取ini文件personal段落的所有键名,返回byte[]类型
    34 
    35 byte[] sectionByte = ini.IniReadValues("personal", null);
    36 
    37  
    38 
    39 //读取ini文件evideo段落的MODEL键值
    40 
    41 model = ini.IniReadValue("evideo", "MODEL");
    42 
    43  
    44 
    45 //将值eth0写入ini文件evideo段落的DEVICE键
    46 
    47 ini.IniWriteValue("evideo", "DEVICE", "eth0");
    48 
    49 即:
    50 
    51 [evideo]
    52 
    53 DEVICE = eth0
    54 
    55  
    56 
    57 //删除ini文件下personal段落下的所有键
    58 
    59 ini.IniWriteValue("personal", null, null);
    60 
    61  
    62 
    63 //删除ini文件下所有段落
    64 
    65 ini.IniWriteValue(null, null, null);

    创建Ini参考:http://blog.csdn.net/sdfkfkd/article/details/7050733

  • 相关阅读:
    Sharding-JDBC(三)3.1.0版本实践
    Sharding-JDBC(二)2.0.3版本实践
    Sharding-JDBC(一)简介
    Java并发(六)线程池监控
    Java并发(五)线程池使用番外-分析RejectedExecutionException异常
    Java并发(四)线程池使用
    Java并发(三)线程池原理
    Java并发(二)异步转同步
    tarjan+概率
    线段树(种树)
  • 原文地址:https://www.cnblogs.com/pyffcwj/p/3379623.html
Copyright © 2011-2022 走看看