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 /// 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); } ///class. /// /// 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. /// 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(); } /// /// or are /// a null reference (Nothing in VB) /// /// /// /// /// /// Gets the value of a setting in an ini file as a . /// /// The value of the key, if found. Otherwise, returns /// . public int GetInt16(string sectionName, string keyName, short defaultValue) { int retval = GetInt32(sectionName, keyName, defaultValue); return Convert.ToInt16(retval); } /// /// or are /// a null reference (Nothing in VB) /// /// /// /// /// /// Gets the value of a setting in an ini file as a . /// /// The value of the key, if found. Otherwise, returns /// 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); } /// /// or are /// a null reference (Nothing in VB) /// /// /// /// /// /// Gets the value of a setting in an ini file as a . /// /// The value of the key, if found. Otherwise, returns /// 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 /// /// or are /// a null reference (Nothing in VB) /// /// /// /// 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. /// public List /// is a null reference (Nothing in VB) /// > 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."); }