zoukankan      html  css  js  c++  java
  • C#如何读写和创建INI文件

    在做项目过程中,有时需要保存一些简单的配置信息,可以使用xml,也可以使用INI文件。下面是C#中读取INI的方法,相信大部分朋友都使用过这种方式。
    INI文件的存储方式如下,

    [csharp] view plain copy
     
     print?
    1. [section]  
    2. key=value  
    3. key=value  

    读取写入方法,

    [csharp] view plain copy
     
     print?
    1. [DllImport("kernel32")]  
    2. private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);  
    3.   
    4. [DllImport("kernel32")]  
    5. private static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);  
    6.   
    7. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]  
    8. private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);  
    9.   
    10. private static string ReadString(string section, string key, string def, string filePath)  
    11. {  
    12.     StringBuilder temp = new StringBuilder(1024);  
    13.   
    14.     try  
    15.     {  
    16.         GetPrivateProfileString(section, key, def, temp, 1024, filePath);  
    17.     }  
    18.     catch  
    19.     { }  
    20.     return temp.ToString();  
    21. }  
    22. /// <summary>  
    23. /// 根据section取所有key  
    24. /// </summary>  
    25. /// <param name="section"></param>  
    26. /// <param name="filePath"></param>  
    27. /// <returns></returns>  
    28. public static string[] ReadIniAllKeys(string section,string filePath)  
    29. {  
    30.     UInt32 MAX_BUFFER = 32767;    
    31.   
    32.     string[] items = new string[0];    
    33.   
    34.     IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));  
    35.   
    36.     UInt32 bytesReturned = GetPrivateProfileSection(section, pReturnedString, MAX_BUFFER, filePath);  
    37.   
    38.     if (!(bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0))  
    39.     {  
    40.         string returnedString = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned);  
    41.   
    42.         items = returnedString.Split(new char[] { '' }, StringSplitOptions.RemoveEmptyEntries);  
    43.     }  
    44.   
    45.     Marshal.FreeCoTaskMem(pReturnedString);   
    46.   
    47.     return items;  
    48. }  
    49.   
    50. /// <summary>  
    51. /// 根据section,key取值  
    52. /// </summary>  
    53. /// <param name="section"></param>  
    54. /// <param name="keys"></param>  
    55. /// <param name="filePath">ini文件路径</param>  
    56. /// <returns></returns>  
    57. public static string ReadIniKeys(string section, string keys, string filePath)  
    58. {  
    59.     return ReadString(section, keys, "", filePath);  
    60. }  
    61.   
    62. /// <summary>  
    63. /// 保存ini  
    64. /// </summary>  
    65. /// <param name="section"></param>  
    66. /// <param name="key"></param>  
    67. /// <param name="value"></param>  
    68. /// <param name="filePath">ini文件路径</param>  
    69. public static void WriteIniKeys(string section, string key, string value, string filePath)  
    70. {  
    71.     WritePrivateProfileString(section, key, value, filePath);  
    72. }  

    如果要删除某一项:

    [csharp] view plain copy
     
     print?
    1. WriteIniKeys(section, key, null, recordIniPath);  

    如上就可以读取和写入了,那么INI文件如何创建呢?

    [csharp] view plain copy
     
     print?
    1. [DllImport("kernel32")]  
    2. public static extern long WritePrivateProfileString(string section, string key, string value, string iniPath);  

    调用该方法,即可创建你的ini文件和想要保存的值。

    当然上面的ini操作并不是很详细的,以下从http://blog.csdn.net/sdfkfkd/article/details/7050733的博客转载的一片描述INI操作的,比较详细,值得学习。

    [csharp] view plain copy
     
     print?
    1. public class INIOperationClass  
    2. {  
    3.  
    4.     #region INI文件操作  
    5.   
    6.     /* 
    7.      * 针对INI文件的API操作方法,其中的节点(Section)、键(KEY)都不区分大小写 
    8.      * 如果指定的INI文件不存在,会自动创建该文件。 
    9.      *  
    10.      * CharSet定义的时候使用了什么类型,在使用相关方法时必须要使用相应的类型 
    11.      *      例如 GetPrivateProfileSectionNames声明为CharSet.Auto,那么就应该使用 Marshal.PtrToStringAuto来读取相关内容 
    12.      *      如果使用的是CharSet.Ansi,就应该使用Marshal.PtrToStringAnsi来读取内容 
    13.      *       
    14.      */  
    15.  
    16.     #region API声明  
    17.   
    18.     /// <summary>  
    19.     /// 获取所有节点名称(Section)  
    20.     /// </summary>  
    21.     /// <param name="lpszReturnBuffer">存放节点名称的内存地址,每个节点之间用分隔</param>  
    22.     /// <param name="nSize">内存大小(characters)</param>  
    23.     /// <param name="lpFileName">Ini文件</param>  
    24.     /// <returns>内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够</returns>  
    25.     [DllImport("kernel32.dll", CharSet = CharSet.Auto)]  
    26.     private static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer, uint nSize, string lpFileName);  
    27.   
    28.     /// <summary>  
    29.     /// 获取某个指定节点(Section)中所有KEY和Value  
    30.     /// </summary>  
    31.     /// <param name="lpAppName">节点名称</param>  
    32.     /// <param name="lpReturnedString">返回值的内存地址,每个之间用分隔</param>  
    33.     /// <param name="nSize">内存大小(characters)</param>  
    34.     /// <param name="lpFileName">Ini文件</param>  
    35.     /// <returns>内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够</returns>  
    36.     [DllImport("kernel32.dll", CharSet = CharSet.Auto)]  
    37.     private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);  
    38.   
    39.     /// <summary>  
    40.     /// 读取INI文件中指定的Key的值  
    41.     /// </summary>  
    42.     /// <param name="lpAppName">节点名称。如果为null,则读取INI中所有节点名称,每个节点名称之间用分隔</param>  
    43.     /// <param name="lpKeyName">Key名称。如果为null,则读取INI中指定节点中的所有KEY,每个KEY之间用分隔</param>  
    44.     /// <param name="lpDefault">读取失败时的默认值</param>  
    45.     /// <param name="lpReturnedString">读取的内容缓冲区,读取之后,多余的地方使用填充</param>  
    46.     /// <param name="nSize">内容缓冲区的长度</param>  
    47.     /// <param name="lpFileName">INI文件名</param>  
    48.     /// <returns>实际读取到的长度</returns>  
    49.     [DllImport("kernel32.dll", CharSet = CharSet.Auto)]  
    50.     private static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, [In, Out] char[] lpReturnedString, uint nSize, string lpFileName);  
    51.   
    52.     //另一种声明方式,使用 StringBuilder 作为缓冲区类型的缺点是不能接受字符,会将及其后的字符截断,  
    53.     //所以对于lpAppName或lpKeyName为null的情况就不适用  
    54.     [DllImport("kernel32.dll", CharSet = CharSet.Auto)]  
    55.     private static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, uint nSize, string lpFileName);  
    56.   
    57.     //再一种声明,使用string作为缓冲区的类型同char[]  
    58.     [DllImport("kernel32.dll", CharSet = CharSet.Auto)]  
    59.     private static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, string lpReturnedString, uint nSize, string lpFileName);  
    60.   
    61.     /// <summary>  
    62.     /// 将指定的键值对写到指定的节点,如果已经存在则替换。  
    63.     /// </summary>  
    64.     /// <param name="lpAppName">节点,如果不存在此节点,则创建此节点</param>  
    65.     /// <param name="lpString">Item键值对,多个用分隔,形如key1=value1key2=value2  
    66.     /// <para>如果为string.Empty,则删除指定节点下的所有内容,保留节点</para>  
    67.     /// <para>如果为null,则删除指定节点下的所有内容,并且删除该节点</para>  
    68.     /// </param>  
    69.     /// <param name="lpFileName">INI文件</param>  
    70.     /// <returns>是否成功写入</returns>  
    71.     [DllImport("kernel32.dll", CharSet = CharSet.Auto)]  
    72.     [return: MarshalAs(UnmanagedType.Bool)]     //可以没有此行  
    73.     private static extern bool WritePrivateProfileSection(string lpAppName, string lpString, string lpFileName);  
    74.   
    75.     /// <summary>  
    76.     /// 将指定的键和值写到指定的节点,如果已经存在则替换  
    77.     /// </summary>  
    78.     /// <param name="lpAppName">节点名称</param>  
    79.     /// <param name="lpKeyName">键名称。如果为null,则删除指定的节点及其所有的项目</param>  
    80.     /// <param name="lpString">值内容。如果为null,则删除指定节点中指定的键。</param>  
    81.     /// <param name="lpFileName">INI文件</param>  
    82.     /// <returns>操作是否成功</returns>  
    83.     [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]  
    84.     [return: MarshalAs(UnmanagedType.Bool)]  
    85.     private static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);  
    86.  
    87.     #endregion  
    88.  
    89.     #region 封装  
    90.   
    91.     /// <summary>  
    92.     /// 读取INI文件中指定INI文件中的所有节点名称(Section)  
    93.     /// </summary>  
    94.     /// <param name="iniFile">Ini文件</param>  
    95.     /// <returns>所有节点,没有内容返回string[0]</returns>  
    96.     public static string[] INIGetAllSectionNames(string iniFile)  
    97.     {  
    98.         uint MAX_BUFFER = 32767;    //默认为32767  
    99.   
    100.         string[] sections = new string[0];      //返回值  
    101.   
    102.         //申请内存  
    103.         IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));  
    104.         uint bytesReturned = INIOperationClass.GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, iniFile);  
    105.         if (bytesReturned != 0)  
    106.         {  
    107.             //读取指定内存的内容  
    108.             string local = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned).ToString();  
    109.   
    110.             //每个节点之间用分隔,末尾有一个  
    111.             sections = local.Split(new char[] { '' }, StringSplitOptions.RemoveEmptyEntries);  
    112.         }  
    113.   
    114.         //释放内存  
    115.         Marshal.FreeCoTaskMem(pReturnedString);  
    116.   
    117.         return sections;  
    118.     }  
    119.   
    120.     /// <summary>  
    121.     /// 获取INI文件中指定节点(Section)中的所有条目(key=value形式)  
    122.     /// </summary>  
    123.     /// <param name="iniFile">Ini文件</param>  
    124.     /// <param name="section">节点名称</param>  
    125.     /// <returns>指定节点中的所有项目,没有内容返回string[0]</returns>  
    126.     public static string[] INIGetAllItems(string iniFile, string section)  
    127.     {  
    128.         //返回值形式为 key=value,例如 Color=Red  
    129.         uint MAX_BUFFER = 32767;    //默认为32767  
    130.   
    131.         string[] items = new string[0];      //返回值  
    132.   
    133.         //分配内存  
    134.         IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));  
    135.   
    136.         uint bytesReturned = INIOperationClass.GetPrivateProfileSection(section, pReturnedString, MAX_BUFFER, iniFile);  
    137.   
    138.         if (!(bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0))  
    139.         {  
    140.   
    141.             string returnedString = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned);  
    142.             items = returnedString.Split(new char[] { '' }, StringSplitOptions.RemoveEmptyEntries);  
    143.         }  
    144.   
    145.         Marshal.FreeCoTaskMem(pReturnedString);     //释放内存  
    146.   
    147.         return items;  
    148.     }  
    149.   
    150.     /// <summary>  
    151.     /// 获取INI文件中指定节点(Section)中的所有条目的Key列表  
    152.     /// </summary>  
    153.     /// <param name="iniFile">Ini文件</param>  
    154.     /// <param name="section">节点名称</param>  
    155.     /// <returns>如果没有内容,反回string[0]</returns>  
    156.     public static string[] INIGetAllItemKeys(string iniFile, string section)  
    157.     {  
    158.         string[] value = new string[0];  
    159.         const int SIZE = 1024 * 10;  
    160.   
    161.         if (string.IsNullOrEmpty(section))  
    162.         {  
    163.             throw new ArgumentException("必须指定节点名称", "section");  
    164.         }  
    165.   
    166.         char[] chars = new char[SIZE];  
    167.         uint bytesReturned = INIOperationClass.GetPrivateProfileString(section, null, null, chars, SIZE, iniFile);  
    168.   
    169.         if (bytesReturned != 0)  
    170.         {  
    171.             value = new string(chars).Split(new char[] { '' }, StringSplitOptions.RemoveEmptyEntries);  
    172.         }  
    173.         chars = null;  
    174.   
    175.         return value;  
    176.     }  
    177.   
    178.     /// <summary>  
    179.     /// 读取INI文件中指定KEY的字符串型值  
    180.     /// </summary>  
    181.     /// <param name="iniFile">Ini文件</param>  
    182.     /// <param name="section">节点名称</param>  
    183.     /// <param name="key">键名称</param>  
    184.     /// <param name="defaultValue">如果没此KEY所使用的默认值</param>  
    185.     /// <returns>读取到的值</returns>  
    186.     public static string INIGetStringValue(string iniFile, string section, string key, string defaultValue)  
    187.     {  
    188.         string value = defaultValue;  
    189.         const int SIZE = 1024 * 10;  
    190.   
    191.         if (string.IsNullOrEmpty(section))  
    192.         {  
    193.             throw new ArgumentException("必须指定节点名称", "section");  
    194.         }  
    195.   
    196.         if (string.IsNullOrEmpty(key))  
    197.         {  
    198.             throw new ArgumentException("必须指定键名称(key)", "key");  
    199.         }  
    200.   
    201.         StringBuilder sb = new StringBuilder(SIZE);  
    202.         uint bytesReturned = INIOperationClass.GetPrivateProfileString(section, key, defaultValue, sb, SIZE, iniFile);  
    203.   
    204.         if (bytesReturned != 0)  
    205.         {  
    206.             value = sb.ToString();  
    207.         }  
    208.         sb = null;  
    209.   
    210.         return value;  
    211.     }  
    212.   
    213.     /// <summary>  
    214.     /// 在INI文件中,将指定的键值对写到指定的节点,如果已经存在则替换  
    215.     /// </summary>  
    216.     /// <param name="iniFile">INI文件</param>  
    217.     /// <param name="section">节点,如果不存在此节点,则创建此节点</param>  
    218.     /// <param name="items">键值对,多个用分隔,形如key1=value1key2=value2</param>  
    219.     /// <returns></returns>  
    220.     public static bool INIWriteItems(string iniFile, string section, string items)  
    221.     {  
    222.         if (string.IsNullOrEmpty(section))  
    223.         {  
    224.             throw new ArgumentException("必须指定节点名称", "section");  
    225.         }  
    226.   
    227.         if (string.IsNullOrEmpty(items))  
    228.         {  
    229.             throw new ArgumentException("必须指定键值对", "items");  
    230.         }  
    231.   
    232.         return INIOperationClass.WritePrivateProfileSection(section, items, iniFile);  
    233.     }  
    234.   
    235.     /// <summary>  
    236.     /// 在INI文件中,指定节点写入指定的键及值。如果已经存在,则替换。如果没有则创建。  
    237.     /// </summary>  
    238.     /// <param name="iniFile">INI文件</param>  
    239.     /// <param name="section">节点</param>  
    240.     /// <param name="key">键</param>  
    241.     /// <param name="value">值</param>  
    242.     /// <returns>操作是否成功</returns>  
    243.     public static bool INIWriteValue(string iniFile, string section, string key, string value)  
    244.     {  
    245.         if (string.IsNullOrEmpty(section))  
    246.         {  
    247.             throw new ArgumentException("必须指定节点名称", "section");  
    248.         }  
    249.   
    250.         if (string.IsNullOrEmpty(key))  
    251.         {  
    252.             throw new ArgumentException("必须指定键名称", "key");  
    253.         }  
    254.   
    255.         if (value == null)  
    256.         {  
    257.             throw new ArgumentException("值不能为null", "value");  
    258.         }  
    259.   
    260.         return INIOperationClass.WritePrivateProfileString(section, key, value, iniFile);  
    261.   
    262.     }  
    263.   
    264.     /// <summary>  
    265.     /// 在INI文件中,删除指定节点中的指定的键。  
    266.     /// </summary>  
    267.     /// <param name="iniFile">INI文件</param>  
    268.     /// <param name="section">节点</param>  
    269.     /// <param name="key">键</param>  
    270.     /// <returns>操作是否成功</returns>  
    271.     public static bool INIDeleteKey(string iniFile, string section, string key)  
    272.     {  
    273.         if (string.IsNullOrEmpty(section))  
    274.         {  
    275.             throw new ArgumentException("必须指定节点名称", "section");  
    276.         }  
    277.   
    278.         if (string.IsNullOrEmpty(key))  
    279.         {  
    280.             throw new ArgumentException("必须指定键名称", "key");  
    281.         }  
    282.   
    283.         return INIOperationClass.WritePrivateProfileString(section, key, null, iniFile);  
    284.     }  
    285.   
    286.     /// <summary>  
    287.     /// 在INI文件中,删除指定的节点。  
    288.     /// </summary>  
    289.     /// <param name="iniFile">INI文件</param>  
    290.     /// <param name="section">节点</param>  
    291.     /// <returns>操作是否成功</returns>  
    292.     public static bool INIDeleteSection(string iniFile, string section)  
    293.     {  
    294.         if (string.IsNullOrEmpty(section))  
    295.         {  
    296.             throw new ArgumentException("必须指定节点名称", "section");  
    297.         }  
    298.   
    299.         return INIOperationClass.WritePrivateProfileString(section, null, null, iniFile);  
    300.     }  
    301.   
    302.     /// <summary>  
    303.     /// 在INI文件中,删除指定节点中的所有内容。  
    304.     /// </summary>  
    305.     /// <param name="iniFile">INI文件</param>  
    306.     /// <param name="section">节点</param>  
    307.     /// <returns>操作是否成功</returns>  
    308.     public static bool INIEmptySection(string iniFile, string section)  
    309.     {  
    310.         if (string.IsNullOrEmpty(section))  
    311.         {  
    312.             throw new ArgumentException("必须指定节点名称", "section");  
    313.         }  
    314.   
    315.         return INIOperationClass.WritePrivateProfileSection(section, string.Empty, iniFile);  
    316.     }  
    317.   
    318.   
    319.     private void TestIniINIOperation()  
    320.     {  
    321.   
    322.         string file = "F:\TestIni.ini";  
    323.   
    324.         //写入/更新键值  
    325.         INIWriteValue(file, "Desktop", "Color", "Red");  
    326.         INIWriteValue(file, "Desktop", "Width", "3270");  
    327.   
    328.         INIWriteValue(file, "Toolbar", "Items", "Save,Delete,Open");  
    329.         INIWriteValue(file, "Toolbar", "Dock", "True");  
    330.   
    331.         //写入一批键值  
    332.         INIWriteItems(file, "Menu", "File=文件View=视图Edit=编辑");  
    333.   
    334.         //获取文件中所有的节点  
    335.         string[] sections = INIGetAllSectionNames(file);  
    336.   
    337.         //获取指定节点中的所有项  
    338.         string[] items = INIGetAllItems(file, "Menu");  
    339.   
    340.         //获取指定节点中所有的键  
    341.         string[] keys = INIGetAllItemKeys(file, "Menu");  
    342.   
    343.         //获取指定KEY的值  
    344.         string value = INIGetStringValue(file, "Desktop", "color", null);  
    345.   
    346.         //删除指定的KEY  
    347.         INIDeleteKey(file, "desktop", "color");  
    348.   
    349.         //删除指定的节点  
    350.         INIDeleteSection(file, "desktop");  
    351.   
    352.         //清空指定的节点  
    353.         INIEmptySection(file, "toolbar");  
    354.   
    355.     }  
    356.     #endregion  
    357.  
    358.     #endregion  
    359. }  
  • 相关阅读:
    事务传播机制,搞懂。
    洛谷 P1553 数字反转(升级版) 题解
    洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is Here 题解
    洛谷 P1055 ISBN号码 题解
    洛谷 P2141 珠心算测验 题解
    洛谷 P1047 校门外的树 题解
    洛谷 P1980 计数问题 题解
    洛谷 P1008 三连击 题解
    HDU 1013 题解
    HDU 1012 题解
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/5433156.html
Copyright © 2011-2022 走看看