C#操作ini文件类

类的代码如下:

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Collections.Generic;

namespace Utilities
{
    ///  
    /// Provides methods for reading and writing to an INI file. 
    ///  
    public class IniFile
    {
        ///  
        /// The maximum size of a section in an ini file. 
        ///  
        ///  
        /// This property defines the maximum size of the buffers 
        /// used to retreive data from an ini file.  This value is 
        /// the maximum allowed by the win32 functions 
        /// GetPrivateProfileSectionNames() or 
        /// GetPrivateProfileString(). 
        ///  
        public const int MaxSectionSize = 32767; // 32 KB 

        //The path of the file we are operating on. 
        private string m_path;

        #region P/Invoke declares

        ///  
        /// A static class that provides the win32 P/Invoke signatures 
        /// used by this class. 
        ///  
        ///  
        /// Note:  In each of the declarations below, we explicitly set CharSet to 
        /// Auto.  By default in C#, CharSet is set to Ansi, which reduces 
        /// performance on windows 2000 and above due to needing to convert strings 
        /// from Unicode (the native format for all .Net strings) to Ansi before 
        /// marshalling.  Using Auto lets the marshaller select the Unicode version of 
        /// these functions when available. 
        ///  
        [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);

            //We explicitly enable the SetLastError attribute here because 
            // WritePrivateProfileString returns errors via SetLastError. 
            // Failure to set this can result in errors being lost during 
            // the marshal back to managed code. 
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern bool WritePrivateProfileString(string lpAppName,
                                                                string lpKeyName,
                                                                string lpString,
                                                                string lpFileName);


        }
        #endregion

        ///  
        /// Initializes a new instance of the  class. 
        ///  
        ///  
        public IniFile(string path)
        {
            //Convert to the full path.  Because of backward compatibility, 
            // the win32 functions tend to assume the path should be the 
            // root Windows directory if it is not specified.  By calling 
            // GetFullPath, we make sure we are always passing the full path 
            // the win32 functions. 
            m_path = System.IO.Path.GetFullPath(path);
        }

        ///  
        /// Gets the full path of ini file this object instance is operating on. 
        ///  
        /// A file path. 
        public string Path
        {
            get
            {
                return m_path;
            }
        }

        #region Get Value Methods

        ///  
        /// Gets the value of a setting in an ini file as a . 
        ///  
        ///  
        ///  
        ///  
        /// The value of the key, if found.  Otherwise, returns 
        ///  
        ///  
        /// The retreived value must be less than 32KB in length. 
        ///  
        ///  
        ///  or  are 
        /// a null reference  (Nothing in VB) 
        ///  
        public string GetString(string sectionName,
                                string keyName,
                                string defaultValue)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            if (keyName == null)
                throw new ArgumentNullException("keyName");

            StringBuilder retval = new StringBuilder(IniFile.MaxSectionSize);

            NativeMethods.GetPrivateProfileString(sectionName,
                                                  keyName,
                                                  defaultValue,
                                                  retval,
                                                  IniFile.MaxSectionSize,
                                                  m_path);

            return retval.ToString();
        }

        ///  
        /// Gets the value of a setting in an ini file as a . 
        ///  
        ///  
        ///  
        ///  
        /// The value of the key, if found.  Otherwise, returns 
        /// . 
        ///  
        ///  or  are 
        /// a null reference  (Nothing in VB) 
        ///  
        public int GetInt16(string sectionName,
                            string keyName,
                            short defaultValue)
        {
            int retval = GetInt32(sectionName, keyName, defaultValue);

            return Convert.ToInt16(retval);
        }

        ///  
        /// Gets the value of a setting in an ini file as a . 
        ///  
        ///  
        ///  
        ///  
        /// The value of the key, if found.  Otherwise, returns 
        ///  
        ///  
        ///  or  are 
        /// a null reference  (Nothing in VB) 
        ///  
        public int GetInt32(string sectionName,
                            string keyName,
                            int defaultValue)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            if (keyName == null)
                throw new ArgumentNullException("keyName");


            return NativeMethods.GetPrivateProfileInt(sectionName, keyName, defaultValue, m_path);
        }

        ///  
        /// Gets the value of a setting in an ini file as a . 
        ///  
        ///  
        ///  
        ///  
        /// The value of the key, if found.  Otherwise, returns 
        ///  
        ///  
        ///  or  are 
        /// a null reference  (Nothing in VB) 
        ///  
        public double GetDouble(string sectionName,
                                string keyName,
                                double defaultValue)
        {
            string retval = GetString(sectionName, keyName, "");

            if (retval == null || retval.Length == 0)
            {
                return defaultValue;
            }

            return Convert.ToDouble(retval, CultureInfo.InvariantCulture);
        }

        #endregion

        #region GetSectionValues Methods

        ///  
        /// Gets all of the values in a section as a list. 
        ///  
        ///  
        ///  
        /// A  containing  objects 
        /// that describe this section.  Use this verison if a section may contain 
        /// multiple items with the same key value.  If you know that a section 
        /// cannot contain multiple values with the same key name or you don't 
        /// care about the duplicates, use the more convenient 
        ///  function. 
        ///  
        ///  
        ///  is a null reference  (Nothing in VB) 
        ///  
        public List> GetSectionValuesAsList(string sectionName)
        {
            List> retval;
            string[] keyValuePairs;
            string key, value;
            int equalSignPos;

            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            //Allocate a buffer for the returned section names. 
            IntPtr ptr = Marshal.AllocCoTaskMem(IniFile.MaxSectionSize);

            try
            {
                //Get the section key/value pairs into the buffer. 
                int len = NativeMethods.GetPrivateProfileSection(sectionName,
                                                                 ptr,
                                                                 IniFile.MaxSectionSize,
                                                                 m_path);

                keyValuePairs = ConvertNullSeperatedStringToStringArray(ptr, len);
            }
            finally
            {
                //Free the buffer 
                Marshal.FreeCoTaskMem(ptr);
            }

            //Parse keyValue pairs and add them to the list. 
            retval = new List>(keyValuePairs.Length);

            for (int i = 0; i < keyValuePairs.Length; ++i)
            {
                //Parse the "key=value" string into its constituent parts 
                equalSignPos = keyValuePairs[i].IndexOf('=');

                key = keyValuePairs[i].Substring(0, equalSignPos);

                value = keyValuePairs[i].Substring(equalSignPos + 1,
                                                   keyValuePairs[i].Length - equalSignPos - 1);

                retval.Add(new KeyValuePair(key, value));
            }

            return retval;
        }

        ///  
        /// Gets all of the values in a section as a dictionary. 
        ///  
        ///  
        ///  
        /// A  containing the key/value 
        /// pairs found in this section.   
        ///  
        ///  
        /// If a section contains more than one key with the same name, 
        /// this function only returns the first instance.  If you need to 
        /// get all key/value pairs within a section even when keys have the 
        /// same name, use . 
        ///  
        ///  
        ///  is a null reference  (Nothing in VB) 
        ///  
        public Dictionary GetSectionValues(string sectionName)
        {
            List> keyValuePairs;
            Dictionary retval;

            keyValuePairs = GetSectionValuesAsList(sectionName);

            //Convert list into a dictionary. 
            retval = new Dictionary(keyValuePairs.Count);

            foreach (KeyValuePair keyValuePair in keyValuePairs)
            {
                //Skip any key we have already seen. 
                if (!retval.ContainsKey(keyValuePair.Key))
                {
                    retval.Add(keyValuePair.Key, keyValuePair.Value);
                }
            }

            return retval;
        }

        #endregion

        #region Get Key/Section Names

        ///  
        /// Gets the names of all keys under a specific section in the ini file. 
        ///  
        ///  
        /// An array of key names. 
        ///  
        /// The total length of all key names in the section must be 
        /// less than 32KB in length. 
        ///  
        ///  
        ///  is a null reference  (Nothing in VB) 
        ///  
        public string[] GetKeyNames(string sectionName)
        {
            int len;
            string[] retval;

            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            //Allocate a buffer for the returned section names. 
            IntPtr ptr = Marshal.AllocCoTaskMem(IniFile.MaxSectionSize);

            try
            {
                //Get the section names into the buffer. 
                len = NativeMethods.GetPrivateProfileString(sectionName,
                                                            null,
                                                            null,
                                                            ptr,
                                                            IniFile.MaxSectionSize,
                                                            m_path);

                retval = ConvertNullSeperatedStringToStringArray(ptr, len);
            }
            finally
            {
                //Free the buffer 
                Marshal.FreeCoTaskMem(ptr);
            }

            return retval;
        }

        ///  
        /// Gets the names of all sections in the ini file. 
        ///  
        /// An array of section names. 
        ///  
        /// The total length of all section names in the section must be 
        /// less than 32KB in length. 
        ///  
        public string[] GetSectionNames()
        {
            string[] retval;
            int len;

            //Allocate a buffer for the returned section names. 
            IntPtr ptr = Marshal.AllocCoTaskMem(IniFile.MaxSectionSize);

            try
            {
                //Get the section names into the buffer. 
                len = NativeMethods.GetPrivateProfileSectionNames(ptr,
                    IniFile.MaxSectionSize, m_path);

                retval = ConvertNullSeperatedStringToStringArray(ptr, len);
            }
            finally
            {
                //Free the buffer 
                Marshal.FreeCoTaskMem(ptr);
            }

            return retval;
        }

        ///  
        /// Converts the null seperated pointer to a string into a string array. 
        ///  
        ///  
        /// . 
        ///  
        ///  
        /// An array of strings; one for each null found in the array of characters pointed 
        /// at by . 
        ///  
        private static string[] ConvertNullSeperatedStringToStringArray(IntPtr ptr, int valLength)
        {
            string[] retval;

            if (valLength == 0)
            {
                //Return an empty array. 
                retval = new string[0];
            }
            else
            {
                //Convert the buffer into a string.  Decrease the length 
                //by 1 so that we remove the second null off the end. 
                string buff = Marshal.PtrToStringAuto(ptr, valLength - 1);

                //Parse the buffer into an array of strings by searching for nulls. 
                retval = buff.Split('\0');
            }

            return retval;
        }

        #endregion

        #region Write Methods

        ///  
        /// Writes a  value to the ini file. 
        ///  
        ///  
        ///  
        ///  
        ///  
        /// The write failed. 
        ///  
        private void WriteValueInternal(string sectionName, string keyName, string value)
        {
            if (!NativeMethods.WritePrivateProfileString(sectionName, keyName, value, m_path))
            {
                throw new System.ComponentModel.Win32Exception();
            }
        }

        ///  
        /// Writes a  value to the ini file. 
        ///  
        ///  
        ///  
        ///  
        ///  
        /// The write failed. 
        ///  
        ///  
        ///  or  or 
        ///   are a null reference  (Nothing in VB) 
        ///  
        public void WriteValue(string sectionName, string keyName, string value)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            if (keyName == null)
                throw new ArgumentNullException("keyName");

            if (value == null)
                throw new ArgumentNullException("value");

            WriteValueInternal(sectionName, keyName, value);
        }

        ///  
        /// Writes an  value to the ini file. 
        ///  
        ///  
        ///  
        ///  
        ///  
        /// The write failed. 
        ///  
        public void WriteValue(string sectionName, string keyName, short value)
        {
            WriteValue(sectionName, keyName, (int)value);
        }

        ///  
        /// Writes an  value to the ini file. 
        ///  
        ///  
        ///  
        ///  
        ///  
        /// The write failed. 
        ///  
        ///  
        ///  or  are 
        /// a null reference  (Nothing in VB) 
        ///  
        public void WriteValue(string sectionName, string keyName, int value)
        {
            WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));
        }

        ///  
        /// Writes an  value to the ini file. 
        ///  
        ///  
        ///  
        ///  
        ///  
        /// The write failed. 
        ///  
        ///  
        ///  or  are 
        /// a null reference  (Nothing in VB) 
        ///  
        public void WriteValue(string sectionName, string keyName, float value)
        {
            WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));
        }

        ///  
        /// Writes an  value to the ini file. 
        ///  
        ///  
        ///  
        ///  
        ///  
        /// The write failed. 
        ///  
        ///  
        ///  or  are 
        /// a null reference  (Nothing in VB) 
        ///  
        public void WriteValue(string sectionName, string keyName, double value)
        {
            WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));
        }

        #endregion

        #region Delete Methods

        ///  
        /// Deletes the specified key from the specified section. 
        ///  
        ///  
        ///  
        ///  
        ///  or  are 
        /// a null reference  (Nothing in VB) 
        ///  
        public void DeleteKey(string sectionName, string keyName)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            if (keyName == null)
                throw new ArgumentNullException("keyName");

            WriteValueInternal(sectionName, keyName, null);
        }

        ///  
        /// Deletes a section from the ini file. 
        ///  
        ///  
        ///  
        ///  is a null reference (Nothing in VB) 
        ///  
        public void DeleteSection(string sectionName)
        {
            if (sectionName == null)
                throw new ArgumentNullException("sectionName");

            WriteValueInternal(sectionName, null, null);
        }

        #endregion
    }
}

 

调用方法:

IniFile iniFile = new IniFile("TestIniFile.ini"); 

//Write a int32 value 
iniFile.WriteValue("section1", "键值1", 42); 

//Write a string value 
iniFile.WriteValue("section1", "key2", "This is a test"); 

//Write a double value 
iniFile.WriteValue("section2", "key3", 16.84); 

//Read section/key names 
Console.WriteLine("File sections/keys"); 
Console.WriteLine("-------------------"); 

string[] sections = iniFile.GetSectionNames(); 
foreach (string section in sections) 
{ 
    Console.WriteLine("[" + section + "]"); 

    string[] keys = iniFile.GetKeyNames(section); 

    foreach (string key in keys) 
    { 
        Console.WriteLine(key); 
    } 
} 

Console.WriteLine("\n-------------------\n"); 

//Read int32 value. 
int value1 = iniFile.GetInt32("section1", "key1", 0); 
Console.WriteLine("key1 = " + value1); 

//Read string value. 
string value2 = iniFile.GetString("section1", "key2", "test"); 
Console.WriteLine("key2 = " + value2); 

//Read double value. 
double value3 = iniFile.GetDouble("section2", "key3", 0.0); 
Console.WriteLine("key3 = " + value3); 

Console.WriteLine("\n-------------------\n"); 

//Delete value key2 
Console.WriteLine("Deleting section1/key2"); 
iniFile.DeleteKey("section1", "key2"); 

value2 = iniFile.GetString("section1", "key2", ""); 
Console.WriteLine("key2=" + value2); 

//Delete section2 
Console.WriteLine("Deleting section2"); 
iniFile.DeleteSection("section2"); 

value3 = iniFile.GetDouble("section2", "key3", 0.0); 
Console.WriteLine("key3=" + value3); 

Console.WriteLine("\n-------------------\n"); 

//Test that calling WriteValue with null section, keyName, or 
//value causes a exception 
try 
{ 
    iniFile.WriteValue(null, "key1", "test"); 
    Console.WriteLine("*** No exception on invalid section name ***"); 
} 
catch (ArgumentNullException) 
{ 
    Console.WriteLine("WriteValue correctly threw an exception on null sectionName.");     
} 

try 
{ 
    iniFile.WriteValue("section1", null, "test"); 
    Console.WriteLine("*** No exception on invalid key name ***"); 
} 
catch (ArgumentNullException) 
{ 
    Console.WriteLine("WriteValue correctly threw an exception on null keyName."); 
} 

try 
{ 
    iniFile.WriteValue("section1", "key2", null); 
    Console.WriteLine("*** No exception on invalid value ***"); 
} 
catch (ArgumentNullException) 
{ 
    Console.WriteLine("WriteValue correctly threw an exception on null value."); 
}


 

posted on 2010-08-31 17:37  才君  阅读(131)  评论(0编辑  收藏  举报

导航