.NET框架中是否有可以读写标准.ini文件的类:

[Section]
<keyname>=<value>
...

Delphi有TIniFile组件,我想知道是否有类似的c# ?


当前回答

如果你不需要铃铛和口哨(即部分),这里有一个班轮:

List<(string, string)> ini = File.ReadLines(filename)
  .Select(s => {
     var spl = s.Split('=', 2);
     return spl.Length == 2 ? (spl[0], spl[1]) : (s, "");
   })
   .Select(vt => (vt.Item1.Trim(), vt.Item2.Trim()))
   .Where(vt => vt.Item1 != "")
   .ToList();

写:

File.WriteAllLines(filename, ini.Select(vt => $"{vt.Item1}={vt.Item2}"));

(如果你不关心重复,使用.ToDictionary()而不是.ToList()更容易访问)

其他回答

我发现了这个简单的实现:

http://bytes.com/topic/net/insights/797169-reading-parsing-ini-file-c

能满足我的需要。

下面是如何使用它:

public class TestParser
{
    public static void Main()
    {
        IniParser parser = new IniParser(@"C:\test.ini");

        String newMessage;

        newMessage = parser.GetSetting("appsettings", "msgpart1");
        newMessage += parser.GetSetting("appsettings", "msgpart2");
        newMessage += parser.GetSetting("punctuation", "ex");

        //Returns "Hello World!"
        Console.WriteLine(newMessage);
        Console.ReadLine();
    }
}

代码如下:

using System;
using System.IO;
using System.Collections;

public class IniParser
{
    private Hashtable keyPairs = new Hashtable();
    private String iniFilePath;

    private struct SectionPair
    {
        public String Section;
        public String Key;
    }

    /// <summary>
    /// Opens the INI file at the given path and enumerates the values in the IniParser.
    /// </summary>
    /// <param name="iniPath">Full path to INI file.</param>
    public IniParser(String iniPath)
    {
        TextReader iniFile = null;
        String strLine = null;
        String currentRoot = null;
        String[] keyPair = null;

        iniFilePath = iniPath;

        if (File.Exists(iniPath))
        {
            try
            {
                iniFile = new StreamReader(iniPath);

                strLine = iniFile.ReadLine();

                while (strLine != null)
                {
                    strLine = strLine.Trim().ToUpper();

                    if (strLine != "")
                    {
                        if (strLine.StartsWith("[") && strLine.EndsWith("]"))
                        {
                            currentRoot = strLine.Substring(1, strLine.Length - 2);
                        }
                        else
                        {
                            keyPair = strLine.Split(new char[] { '=' }, 2);

                            SectionPair sectionPair;
                            String value = null;

                            if (currentRoot == null)
                                currentRoot = "ROOT";

                            sectionPair.Section = currentRoot;
                            sectionPair.Key = keyPair[0];

                            if (keyPair.Length > 1)
                                value = keyPair[1];

                            keyPairs.Add(sectionPair, value);
                        }
                    }

                    strLine = iniFile.ReadLine();
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (iniFile != null)
                    iniFile.Close();
            }
        }
        else
            throw new FileNotFoundException("Unable to locate " + iniPath);

    }

    /// <summary>
    /// Returns the value for the given section, key pair.
    /// </summary>
    /// <param name="sectionName">Section name.</param>
    /// <param name="settingName">Key name.</param>
    public String GetSetting(String sectionName, String settingName)
    {
        SectionPair sectionPair;
        sectionPair.Section = sectionName.ToUpper();
        sectionPair.Key = settingName.ToUpper();

        return (String)keyPairs[sectionPair];
    }

    /// <summary>
    /// Enumerates all lines for given section.
    /// </summary>
    /// <param name="sectionName">Section to enum.</param>
    public String[] EnumSection(String sectionName)
    {
        ArrayList tmpArray = new ArrayList();

        foreach (SectionPair pair in keyPairs.Keys)
        {
            if (pair.Section == sectionName.ToUpper())
                tmpArray.Add(pair.Key);
        }

        return (String[])tmpArray.ToArray(typeof(String));
    }

    /// <summary>
    /// Adds or replaces a setting to the table to be saved.
    /// </summary>
    /// <param name="sectionName">Section to add under.</param>
    /// <param name="settingName">Key name to add.</param>
    /// <param name="settingValue">Value of key.</param>
    public void AddSetting(String sectionName, String settingName, String settingValue)
    {
        SectionPair sectionPair;
        sectionPair.Section = sectionName.ToUpper();
        sectionPair.Key = settingName.ToUpper();

        if (keyPairs.ContainsKey(sectionPair))
            keyPairs.Remove(sectionPair);

        keyPairs.Add(sectionPair, settingValue);
    }

    /// <summary>
    /// Adds or replaces a setting to the table to be saved with a null value.
    /// </summary>
    /// <param name="sectionName">Section to add under.</param>
    /// <param name="settingName">Key name to add.</param>
    public void AddSetting(String sectionName, String settingName)
    {
        AddSetting(sectionName, settingName, null);
    }

    /// <summary>
    /// Remove a setting.
    /// </summary>
    /// <param name="sectionName">Section to add under.</param>
    /// <param name="settingName">Key name to add.</param>
    public void DeleteSetting(String sectionName, String settingName)
    {
        SectionPair sectionPair;
        sectionPair.Section = sectionName.ToUpper();
        sectionPair.Key = settingName.ToUpper();

        if (keyPairs.ContainsKey(sectionPair))
            keyPairs.Remove(sectionPair);
    }

    /// <summary>
    /// Save settings to new file.
    /// </summary>
    /// <param name="newFilePath">New file path.</param>
    public void SaveSettings(String newFilePath)
    {
        ArrayList sections = new ArrayList();
        String tmpValue = "";
        String strToSave = "";

        foreach (SectionPair sectionPair in keyPairs.Keys)
        {
            if (!sections.Contains(sectionPair.Section))
                sections.Add(sectionPair.Section);
        }

        foreach (String section in sections)
        {
            strToSave += ("[" + section + "]\r\n");

            foreach (SectionPair sectionPair in keyPairs.Keys)
            {
                if (sectionPair.Section == section)
                {
                    tmpValue = (String)keyPairs[sectionPair];

                    if (tmpValue != null)
                        tmpValue = "=" + tmpValue;

                    strToSave += (sectionPair.Key + tmpValue + "\r\n");
                }
            }

            strToSave += "\r\n";
        }

        try
        {
            TextWriter tw = new StreamWriter(newFilePath);
            tw.Write(strToSave);
            tw.Close();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// Save settings back to ini file.
    /// </summary>
    public void SaveSettings()
    {
        SaveSettings(iniFilePath);
    }
}

我想介绍一个完全用c#创建的IniParser库,所以它不包含任何操作系统的依赖关系,这使得它与Mono兼容。MIT许可的开源软件——所以它可以在任何代码中使用。

你可以在GitHub中查看源代码,它也可以作为NuGet包使用

它是高度可配置的,使用起来非常简单。

很抱歉我不要脸的插播,但我希望它能对那些重新审视这个答案的人有所帮助。

CommonLibrary中有一个Ini解析器。网

这有各种非常方便的重载获取部分/值,是非常轻的重量。

如果你不需要铃铛和口哨(即部分),这里有一个班轮:

List<(string, string)> ini = File.ReadLines(filename)
  .Select(s => {
     var spl = s.Split('=', 2);
     return spl.Length == 2 ? (spl[0], spl[1]) : (s, "");
   })
   .Select(vt => (vt.Item1.Trim(), vt.Item2.Trim()))
   .Where(vt => vt.Item1 != "")
   .ToList();

写:

File.WriteAllLines(filename, ini.Select(vt => $"{vt.Item1}={vt.Item2}"));

(如果你不关心重复,使用.ToDictionary()而不是.ToList()更容易访问)

CodeProject的这篇文章“一个使用c#的INI文件处理类”应该会有所帮助。

作者创建了一个c#类“Ini”,它公开了KERNEL32.dll中的两个函数。这些函数是:WritePrivateProfileString和GetPrivateProfileString。您需要两个命名空间:System.Runtime.InteropServices和System.Text。

使用Ini类的步骤

在项目名称空间定义中添加

using INI;

像这样创建一个INIFile

INIFile ini = new INIFile("C:\\test.ini");

使用IniWriteValue向section中的特定键写入新值,或使用IniReadValue从特定section中的键读取值。

注意:如果你是从头开始,你可以阅读这篇MSDN文章:如何:将应用程序配置文件添加到c#项目。这是配置应用程序的一种更好的方式。