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. }  
  • 相关阅读:
    流程设计器的界面设计
    业务系统如何集成工作流系统
    初生牛犊式工作流系统
    任务提醒功能的实现
    动态分支在工作流中的应用
    流程实例运行轨迹的运用
    工作流系统之轨迹备注
    曾经迷茫的起点,多年后终于明白了(续)
    自己编写多线程类并发测试工作流系统(仿吉日老大的测试方法)
    Web自定义表单工具和协同办公系统之集成(1)
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/5433156.html
Copyright © 2011-2022 走看看