使用 C# 的 INI 文件枚举器类






3.67/5 (7投票s)
使用 C# 的 INI 文件枚举器类。
引言
我在互联网上找到了一些使用 KERNEL32.DLL 中的 GetPrivateProfileString
函数的代码片段,但它们都没有提供我所需的功能。因此,我创建了一个 C# 类 INI,它公开了这个函数,并利用了这些代码片段中的最佳元素。
首先,创建一个新的 C# 控制台应用程序。然后,添加一个新的 C# 类。我将其命名为 ReadINI.cs。现在,将第一段代码复制并粘贴到这个新类中。然后,将第二段代码复制到 C# 主控制台应用程序类中。现在,在 C:\ 的根目录下创建一个基本的 INI 文件,名为 Test.ini。
[TestSectionHeader1]
TestKey11 = TestValue11
TestKey12 = TestValue12
TestKey13 = TestValue13
TestKey14 = TestValue14
TestKey15 = TestValue15
[TestSectionHeader2]
TestKey21 = TestValue21
TestKey22 = TestValue22
TestKey23 = TestValue23
TestKey24 = TestValue24
TestKey25 = TestValue25
[TestSectionHeader3]
TestKey31 = TestValue31
TestKey32 = TestValue32
TestKey33 = TestValue33
TestKey34 = TestValue34
TestKey35 = TestValue35
类
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace INI
{
// Set the IniFileName class within the INI Namespace.
public class IniFileName
{
// Imports the Win32 Function "GetPrivateProfileString"
/// from the "Kernel32" class.
// I use 3 methods to gather the information. All have the same name
// as defind by the Win32 Function "GetPrivateProfileString"
//
// First Method, Gathers the Value, as the SectionHeader and EntryKey are know.
//
// Second Method, Gathers a list of EntryKey for the known SectionHeader
//
// Third Method, Gathers a list of SectionHeaders.
// First Method
[DllImport ("kernel32")]
static extern int GetPrivateProfileString (string Section, string Key,
string Value, StringBuilder Result, int Size, string FileName);
// Second Method
[DllImport ("kernel32")]
static extern int GetPrivateProfileString (string Section, int Key,
string Value, [MarshalAs (UnmanagedType.LPArray)] byte[] Result,
int Size, string FileName);
// Third Method
[DllImport ("kernel32")]
static extern int GetPrivateProfileString (int Section, string Key,
string Value, [MarshalAs (UnmanagedType.LPArray)] byte[] Result,
int Size, string FileName);
// Set the IniFileName passed from the Main Application.
public string path;
public IniFileName(string INIPath)
{
path = INIPath;
}
// The Function called to obtain the SectionHeaders,
// and returns them in an Dynamic Array.
public string[] GetSectionNames()
{
// Sets the maxsize buffer to 500, if the more
// is required then doubles the size each time.
for (int maxsize = 500; true; maxsize*=2)
{
// Obtains the information in bytes and stores
// them in the maxsize buffer (Bytes array)
byte[] bytes = new byte[maxsize];
int size = GetPrivateProfileString(0,"","",bytes,maxsize,path);
// Check the information obtained is not bigger
// than the allocated maxsize buffer - 2 bytes.
// if it is, then skip over the next section
// so that the maxsize buffer can be doubled.
if (size < maxsize -2)
{
// Converts the bytes value into an ASCII char. This is one long string.
string Selected = Encoding.ASCII.GetString(bytes,0,
size - (size >0 ? 1:0));
// Splits the Long string into an array based on the "\0"
// or null (Newline) value and returns the value(s) in an array
return Selected.Split(new char[] {'\0'});
}
}
}
// The Function called to obtain the EntryKey's from the given
// SectionHeader string passed and returns them in an Dynamic Array
public string[] GetEntryNames(string section)
{
// Sets the maxsize buffer to 500, if the more
// is required then doubles the size each time.
for (int maxsize = 500; true; maxsize*=2)
{
// Obtains the EntryKey information in bytes
// and stores them in the maxsize buffer (Bytes array).
// Note that the SectionHeader value has been passed.
byte[] bytes = new byte[maxsize];
int size = GetPrivateProfileString(section,0,"",bytes,maxsize,path);
// Check the information obtained is not bigger
// than the allocated maxsize buffer - 2 bytes.
// if it is, then skip over the next section
// so that the maxsize buffer can be doubled.
if (size < maxsize -2)
{
// Converts the bytes value into an ASCII char.
// This is one long string.
string entries = Encoding.ASCII.GetString(bytes,0,
size - (size >0 ? 1:0));
// Splits the Long string into an array based on the "\0"
// or null (Newline) value and returns the value(s) in an array
return entries.Split(new char[] {'\0'});
}
}
}
// The Function called to obtain the EntryKey Value from
// the given SectionHeader and EntryKey string passed, then returned
public object GetEntryValue(string section, string entry)
{
// Sets the maxsize buffer to 250, if the more
// is required then doubles the size each time.
for (int maxsize = 250; true;maxsize *=2)
{
// Obtains the EntryValue information and uses the StringBuilder
// Function to and stores them in the maxsize buffers (result).
// Note that the SectionHeader and EntryKey values has been passed.
StringBuilder result = new StringBuilder(maxsize);
int size = GetPrivateProfileString(section,entry,"",
result, maxsize,path);
if (size < maxsize -1)
{
// Returns the value gathered from the EntryKey
return result.ToString();
}
}
}
}
}
现在,是主 C# 控制台应用程序类。
我包含了两个例程来收集信息。第一个是在代码主体中的 foreach
循环。第二个在代码末尾注释掉了,并使用了 IEnumerator
函数。两者产生相同的结果。
using System;
using System.Collections;
// Set the system to using the INI Namespace within the ReadINI Class
using INI;
namespace MainApp
{
// Basic Console Application that will read a Common Windows INI file
// and display Enumerate Section Headers, Section Entries and Entries Values.
class Class1
{
// The main Console routine.
[STAThread]
static void Main(string[] args)
{
// Sets the INI filename and location to be used.
// remember to use a double slash "\\"
// instead of a single for folder levels.
IniFileName INI = new INI.IniFileName("C:\\test.ini");
// Use the Try comman to gather the information,
// if an error occurs then throw an exception.
// and display the error.
try
{
// set the SectionHeader into an Dynamic Singlelevel Array.
// the Information is gathered from the GetSectionNames
// function INI namespace of the ReadINI Class.
string [] SectionHeader = INI.GetSectionNames();
// Checks to see if the SectionHeader has returned null.
if (SectionHeader != null)
{
// Returns a list EntryKey's for each of the SectionHeader(s).
foreach (string SecHead in SectionHeader)
{
// Write the SectionHeader to the display.
Console.WriteLine(SecHead);
// Sets the Entry Dynamic Array for the each
// of the EntryKeys within the Section Header.
// If you already know the SectionHeader
// and just need to list the Entry's
// then enter the name instead of the SecHead
// in the GetEntrNames function.
// ie. INI.GetEntryNames("TestSecHead")
string [] Entry = INI.GetEntryNames(SecHead);
// Checks to see if there's an Entry under
// the SectionHeader and the Entry has not returned a null
if (Entry != null)
{
// Enumerates a list of Keys For each of the Entry.
foreach (string EntName in Entry)
{
// writes to display the value for the Entry key.
// If you already know the SectionHeader
// and the Entry Key values then, replace all the code
// after the INIFileName line, with the following
// Console.WriteLine(" {0} = {1}", "TestKey",
// INI.GetEntryValue("TestSecHead","TestKey"));
// this will display the Value for the Entry key
// under the given SectionHeader.
Console.WriteLine(" {0} = {1}", EntName,
INI.GetEntryValue(SecHead,EntName));
}
}
}
}
}
// If an error if thrown, catch the exception error
catch (Exception ex)
{
// Write the exception error to the display.
Console.WriteLine("Error: "+ ex);
}
// Waits for a "Enter" key to be used.
// I use this like a pause button.
Console.ReadLine();
}
}
}
/* You can also use the Enumerator function to produce
* the same results. Here is the code if you wish to use that function.
* Replace the code from the "Try" at line 26 until
* the "console.readline()" at line 71 with this.
*
* try
* {
* IEnumerator e = INI.GetSectionNames().GetEnumerator();
* while(e.MoveNext())
* {
* string SectionHead = e.Current.ToString();
* Console.WriteLine(e.Current);
* IEnumerator d = INI.GetEntryNames(SectionHead).GetEnumerator();
* while(d.MoveNext())
* {
* string EntryKey = d.Current.ToString();
* Console.WriteLine("{0} = {1}",
* d.Current,INI.GetEntryValue(SectionHead,EntryKey));
* }
*
* }
* }
* catch (Exception ex)
* {
* Console.WriteLine( "Exception Error: {0}", ex);
* }
* Console.ReadLine();
*
*
*
*
*/
就这样了。运行应用程序以显示您的结果。
关注点
我还以 zip 格式包含了代码供您使用。希望这对某人有所帮助。这是我的第一次发布,请多多包涵。我也可以借此机会感谢所有其他的 C# 大师提供的代码片段,这些片段帮助我完成了我的代码?