65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.67/5 (7投票s)

2008 年 12 月 8 日

CPOL

1分钟阅读

viewsIcon

70025

downloadIcon

1157

使用 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# 大师提供的代码片段,这些片段帮助我完成了我的代码?

© . All rights reserved.