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
///
/// The ini file to read and write from.
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.
///
///
public string Path
{
get
{
return m_path;
}
}
#region Get Value Methods
///
/// Gets the value of a setting in an ini file as a
///
/// The name of the section to read from.
/// The name of the key in section to read.
/// The default value to return if the key
/// cannot be found.
///
///
///
/// The retreived value must be less than 32KB in length.
///
///
///
/// 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 name of the section to read from.
/// The name of the key in section to read.
/// The default value to return if the key
/// cannot be found.
///
///
///
///
/// 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 name of the section to read from.
/// The name of the key in section to read.
/// The default value to return if the key
/// cannot be found.
///
///
///
///
/// 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 name of the section to read from.
/// The name of the key in section to read.
/// The default value to return if the key
/// cannot be found.
///
///
///
///
/// 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.
///
///
/// Name of the section to retrieve values from.
///
///
/// A
/// 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
///
///
///
///
///
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;
}
///
/// Gets all of the values in a section as a dictionary.
///
///
/// Name of the section to retrieve values from.
///
///
/// A
/// 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
///
///
///
///
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
///
/// Gets the names of all keys under a specific section in the ini file.
///
///
/// The name of the section to read key names from.
///
///
///
/// The total length of all key names in the section must be
/// less than 32KB in length.
///
///
///
///
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.
///
///
///
/// 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.
///
/// A pointer to string data.
///
/// Length of the data pointed to by
///
///
/// 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
///
/// The name of the section to write to .
/// The name of the key to write to.
/// The string value to write
///
/// 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
///
/// The name of the section to write to .
/// The name of the key to write to.
/// The string value to write
///
/// The write failed.
///
///
///
///
///
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
///
/// The name of the section to write to .
/// The name of the key to write to.
/// The value to write
///
/// The write failed.
///
public void WriteValue(string sectionName, string keyName, short value)
{
WriteValue(sectionName, keyName, (int)value);
}
///
/// Writes an
///
/// The name of the section to write to .
/// The name of the key to write to.
/// The value to write
///
/// The write failed.
///
///
///
/// a null reference (Nothing in VB)
///
public void WriteValue(string sectionName, string keyName, int value)
{
WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));
}
///
/// Writes an
///
/// The name of the section to write to .
/// The name of the key to write to.
/// The value to write
///
/// The write failed.
///
///
///
/// a null reference (Nothing in VB)
///
public void WriteValue(string sectionName, string keyName, float value)
{
WriteValue(sectionName, keyName, value.ToString(CultureInfo.InvariantCulture));
}
///
/// Writes an
///
/// The name of the section to write to .
/// The name of the key to write to.
/// The value to write
///
/// The write failed.
///
///
///
/// 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.
///
///
/// Name of the section to remove the key from.
///
///
/// Name of the key to remove.
///
///
///
/// 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.
///
///
/// Name of the section to delete.
///
///
///
///
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.");
}