zoukankan      html  css  js  c++  java
  • C# 读写ini文件 【转】

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

    1. [section] 
    2. key=value 
    3. key=value 
    [section]
    key=value
    key=value

    读取写入方法,

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

    如果要删除某一项:

    1. WriteIniKeys(section, key, null, recordIniPath); 
    WriteIniKeys(section, key, null, recordIniPath);

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

    1. [DllImport("kernel32")] 
    2. publicstaticexternlong WritePrivateProfileString(string section, string key, string value, string iniPath); 
    [DllImport("kernel32")]
    public static extern long WritePrivateProfileString(string section, string key, string value, string iniPath);

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

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

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

     来自:http://blog.csdn.net/yysyangyangyangshan/article/details/7017523

  • 相关阅读:
    Nginx降权启动
    Tomcat降权启动
    【转载】XSS学习笔记
    仪仗队(容斥,欧拉,打表)
    2012蓝桥杯
    HPU周赛题目解析
    蓝桥杯真题集2011
    cf公式专场-续
    24点游戏&&速算24点(dfs)
    Parallelogram Counting(平行四边形个数,思维转化)
  • 原文地址:https://www.cnblogs.com/Godblessyou/p/2859381.html
Copyright © 2011-2022 走看看