C#操作 ini文件类【转】

类的代码如下:

using System;

using System.Text;

using System.Runtime.InteropServices;

using System.Globalization;

using System.Collections.Generic;

namespace Utilities

{

/// <summary>

/// Provides methods for reading and writing to an INI file.

/// </summary>

public class IniFile

{

/// <summary>

/// The maximum size of a section in an ini file.

/// </summary>

/// <remarks>

/// 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().

/// </remarks>

public const int MaxSectionSize = 32767; // 32 KB

//The path of the file we are operating on.

private string m_path;

#region P/Invoke declares

/// <summary>

/// A static class that provides the win32 P/Invoke signatures

/// used by this class.

/// </summary>

/// <remarks>

/// 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.

/// </remarks>

[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

/// <summary>

/// Initializes a new instance of the <see cref="IniFile"/> class.

/// </summary>

/// <param name="path">The ini file to read and write from.</param>

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);

}

/// <summary>

/// Gets the full path of ini file this object instance is operating on.

/// </summary>

/// <value>A file path.</value>

public string Path

{

get

{

return m_path;

}

}

#region Get Value Methods

/// <summary>

/// Gets the value of a setting in an ini file as a <see cref="T:System.String"/>.

/// </summary>

/// <param name="sectionName">The name of the section to read from.</param>

/// <param name="keyName">The name of the key in section to read.</param>

/// <param name="defaultValue">The default value to return if the key

/// cannot be found.</param>

/// <returns>The value of the key, if found. Otherwise, returns

/// <paramref name="defaultValue"/></returns>

/// <remarks>

/// The retreived value must be less than 32KB in length.

/// </remarks>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> or <paramref name="keyName"/> are

/// a null reference (Nothing in VB)

/// </exception>

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();

}

/// <summary>

/// Gets the value of a setting in an ini file as a <see cref="T:System.Int16"/>.

/// </summary>

/// <param name="sectionName">The name of the section to read from.</param>

/// <param name="keyName">The name of the key in section to read.</param>

/// <param name="defaultValue">The default value to return if the key

/// cannot be found.</param>

/// <returns>The value of the key, if found. Otherwise, returns

/// <paramref name="defaultValue"/>.</returns>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> or <paramref name="keyName"/> are

/// a null reference (Nothing in VB)

/// </exception>

public int GetInt16(string sectionName,

string keyName,

short defaultValue)

{

int retval = GetInt32(sectionName, keyName, defaultValue);

return Convert.ToInt16(retval);

}

/// <summary>

/// Gets the value of a setting in an ini file as a <see cref="T:System.Int32"/>.

/// </summary>

/// <param name="sectionName">The name of the section to read from.</param>

/// <param name="keyName">The name of the key in section to read.</param>

/// <param name="defaultValue">The default value to return if the key

/// cannot be found.</param>

/// <returns>The value of the key, if found. Otherwise, returns

/// <paramref name="defaultValue"/></returns>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> or <paramref name="keyName"/> are

/// a null reference (Nothing in VB)

/// </exception>

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);

}

/// <summary>

/// Gets the value of a setting in an ini file as a <see cref="T:System.Double"/>.

/// </summary>

/// <param name="sectionName">The name of the section to read from.</param>

/// <param name="keyName">The name of the key in section to read.</param>

/// <param name="defaultValue">The default value to return if the key

/// cannot be found.</param>

/// <returns>The value of the key, if found. Otherwise, returns

/// <paramref name="defaultValue"/></returns>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> or <paramref name="keyName"/> are

/// a null reference (Nothing in VB)

/// </exception>

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

/// <summary>

/// Gets all of the values in a section as a list.

/// </summary>

/// <param name="sectionName">

/// Name of the section to retrieve values from.

/// </param>

/// <returns>

/// A <see cref="List{T}"/> containing <see cref="KeyValuePair{T1, T2}"/> 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

/// <see cref="GetSectionValues"/> function.

/// </returns>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> is a null reference (Nothing in VB)

/// </exception>

public List<KeyValuePair<string, string>> GetSectionValuesAsList(string sectionName)

{

List<KeyValuePair<string, string>> 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<KeyValuePair<string, string>>(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<string, string>(key, value) );

}

return retval;

}

/// <summary>

/// Gets all of the values in a section as a dictionary.

/// </summary>

/// <param name="sectionName">

/// Name of the section to retrieve values from.

/// </param>

/// <returns>

/// A <see cref="Dictionary{T, T}"/> containing the key/value

/// pairs found in this section.

/// </returns>

/// <remarks>

/// 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 <see cref="GetSectionValuesAsList"/>.

/// </remarks>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> is a null reference (Nothing in VB)

/// </exception>

public Dictionary<string, string> GetSectionValues(string sectionName)

{

List<KeyValuePair<string, string>> keyValuePairs;

Dictionary<string, string> retval;

keyValuePairs = GetSectionValuesAsList(sectionName);

//Convert list into a dictionary.

retval = new Dictionary<string, string>(keyValuePairs.Count);

foreach (KeyValuePair<string, string> 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

/// <summary>

/// Gets the names of all keys under a specific section in the ini file.

/// </summary>

/// <param name="sectionName">

/// The name of the section to read key names from.

/// </param>

/// <returns>An array of key names.</returns>

/// <remarks>

/// The total length of all key names in the section must be

/// less than 32KB in length.

/// </remarks>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> is a null reference (Nothing in VB)

/// </exception>

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;

}

/// <summary>

/// Gets the names of all sections in the ini file.

/// </summary>

/// <returns>An array of section names.</returns>

/// <remarks>

/// The total length of all section names in the section must be

/// less than 32KB in length.

/// </remarks>

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;

}

/// <summary>

/// Converts the null seperated pointer to a string into a string array.

/// </summary>

/// <param name="ptr">A pointer to string data.</param>

/// <param name="valLength">

/// Length of the data pointed to by <paramref name="ptr"/>.

/// </param>

/// <returns>

/// An array of strings; one for each null found in the array of characters pointed

/// at by <paramref name="ptr"/>.

/// </returns>

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

/// <summary>

/// Writes a <see cref="T:System.String"/> value to the ini file.

/// </summary>

/// <param name="sectionName">The name of the section to write to .</param>

/// <param name="keyName">The name of the key to write to.</param>

/// <param name="value">The string value to write</param>

/// <exception cref="T:System.ComponentModel.Win32Exception">

/// The write failed.

/// </exception>

private void WriteValueInternal(string sectionName, string keyName, string value)

{

if (!NativeMethods.WritePrivateProfileString(sectionName, keyName, value, m_path))

{

throw new System.ComponentModel.Win32Exception();

}

}

/// <summary>

/// Writes a <see cref="T:System.String"/> value to the ini file.

/// </summary>

/// <param name="sectionName">The name of the section to write to .</param>

/// <param name="keyName">The name of the key to write to.</param>

/// <param name="value">The string value to write</param>

/// <exception cref="T:System.ComponentModel.Win32Exception">

/// The write failed.

/// </exception>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> or <paramref name="keyName"/> or

/// <paramref name="value"/> are a null reference (Nothing in VB)

/// </exception>

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);

}

/// <summary>

/// Writes an <see cref="T:System.Int16"/> value to the ini file.

/// </summary>

/// <param name="sectionName">The name of the section to write to .</param>

/// <param name="keyName">The name of the key to write to.</param>

/// <param name="value">The value to write</param>

/// <exception cref="T:System.ComponentModel.Win32Exception">

/// The write failed.

/// </exception>

public void WriteValue(string sectionName, string keyName, short value)

{

WriteValue(sectionName, keyName, (int)value);

}

/// <summary>

/// Writes an <see cref="T:System.Int32"/> value to the ini file.

/// </summary>

/// <param name="sectionName">The name of the section to write to .</param>

/// <param name="keyName">The name of the key to write to.</param>

/// <param name="value">The value to write</param>

/// <exception cref="T:System.ComponentModel.Win32Exception">

/// The write failed.

/// </exception>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> or <paramref name="keyName"/> are

/// a null reference (Nothing in VB)

/// </exception>

public void WriteValue(string sectionName, string keyName, int value)

{

WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));

}

/// <summary>

/// Writes an <see cref="T:System.Single"/> value to the ini file.

/// </summary>

/// <param name="sectionName">The name of the section to write to .</param>

/// <param name="keyName">The name of the key to write to.</param>

/// <param name="value">The value to write</param>

/// <exception cref="T:System.ComponentModel.Win32Exception">

/// The write failed.

/// </exception>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> or <paramref name="keyName"/> are

/// a null reference (Nothing in VB)

/// </exception>

public void WriteValue(string sectionName, string keyName, float value)

{

WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));

}

/// <summary>

/// Writes an <see cref="T:System.Double"/> value to the ini file.

/// </summary>

/// <param name="sectionName">The name of the section to write to .</param>

/// <param name="keyName">The name of the key to write to.</param>

/// <param name="value">The value to write</param>

/// <exception cref="T:System.ComponentModel.Win32Exception">

/// The write failed.

/// </exception>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> or <paramref name="keyName"/> are

/// a null reference (Nothing in VB)

/// </exception>

public void WriteValue(string sectionName, string keyName, double value)

{

WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));

}

#endregion

#region Delete Methods

/// <summary>

/// Deletes the specified key from the specified section.

/// </summary>

/// <param name="sectionName">

/// Name of the section to remove the key from.

/// </param>

/// <param name="keyName">

/// Name of the key to remove.

/// </param>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> or <paramref name="keyName"/> are

/// a null reference (Nothing in VB)

/// </exception>

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);

}

/// <summary>

/// Deletes a section from the ini file.

/// </summary>

/// <param name="sectionName">

/// Name of the section to delete.

/// </param>

/// <exception cref="ArgumentNullException">

/// <paramref name="sectionName"/> is a null reference (Nothing in VB)

/// </exception>

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.");

}

转自:http://www.cnblogs.com/mccj/archive/2010/08/31/1813894.html