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

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

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


当前回答

INI是一个用于INI文件操作的nuget打包类。它支持读/写,包括注释-写时保留注释。它似乎相当受欢迎,经过测试,易于使用。它也是完全免费和开源的。

免责声明:我是花生酱ini的作者。

其他回答

joerage回答中的代码是鼓舞人心的。

不幸的是,它改变了键的字符大小写,并且不处理注释。所以我写了一些足够健壮的东西,可以读取(只)非常脏的INI文件,并允许按原样检索密钥。

它使用一些LINQ,一个嵌套的不区分大小写的字符串字典来存储节,键和值,并一次性读取文件。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

class IniReader
{
    Dictionary<string, Dictionary<string, string>> ini = new Dictionary<string, Dictionary<string, string>>(StringComparer.InvariantCultureIgnoreCase);

    public IniReader(string file)
    {
        var txt = File.ReadAllText(file);

        Dictionary<string, string> currentSection = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);

        ini[""] = currentSection;

        foreach(var line in txt.Split(new[]{"\n"}, StringSplitOptions.RemoveEmptyEntries)
                               .Where(t => !string.IsNullOrWhiteSpace(t))
                               .Select(t => t.Trim()))
        {
            if (line.StartsWith(";"))
                continue;

            if (line.StartsWith("[") && line.EndsWith("]"))
            {
                currentSection = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
                ini[line.Substring(1, line.LastIndexOf("]") - 1)] = currentSection;
                continue;
            }

            var idx = line.IndexOf("=");
            if (idx == -1)
                currentSection[line] = "";
            else
                currentSection[line.Substring(0, idx)] = line.Substring(idx + 1);
        }
    }

    public string GetValue(string key)
    {
        return GetValue(key, "", "");
    }

    public string GetValue(string key, string section)
    {
        return GetValue(key, section, "");
    }

    public string GetValue(string key, string section, string @default)
    {
        if (!ini.ContainsKey(section))
            return @default;

        if (!ini[section].ContainsKey(key))
            return @default;

        return ini[section][key];
    }

    public string[] GetKeys(string section)
    {
        if (!ini.ContainsKey(section))
            return new string[0];

        return ini[section].Keys.ToArray();
    }

    public string[] GetSections()
    {
        return ini.Keys.Where(t => t != "").ToArray();
    }
}

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

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()更容易访问)

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

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

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

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

这是我的班级,效果非常好:

public static class IniFileManager
{


    [DllImport("kernel32")]
    private static extern long WritePrivateProfileString(string section,
        string key, string val, string filePath);
    [DllImport("kernel32")]
    private static extern int GetPrivateProfileString(string section,
             string key, string def, StringBuilder retVal,
        int size, string filePath);
    [DllImport("kernel32.dll")]
    private static extern int GetPrivateProfileSection(string lpAppName,
             byte[] lpszReturnBuffer, int nSize, string lpFileName);


    /// <summary>
    /// Write Data to the INI File
    /// </summary>
    /// <PARAM name="Section"></PARAM>
    /// Section name
    /// <PARAM name="Key"></PARAM>
    /// Key Name
    /// <PARAM name="Value"></PARAM>
    /// Value Name
    public static void IniWriteValue(string sPath,string Section, string Key, string Value)
    {
        WritePrivateProfileString(Section, Key, Value, sPath);
    }

    /// <summary>
    /// Read Data Value From the Ini File
    /// </summary>
    /// <PARAM name="Section"></PARAM>
    /// <PARAM name="Key"></PARAM>
    /// <PARAM name="Path"></PARAM>
    /// <returns></returns>
    public static string IniReadValue(string sPath,string Section, string Key)
    {
        StringBuilder temp = new StringBuilder(255);
        int i = GetPrivateProfileString(Section, Key, "", temp,
                                        255, sPath);
        return temp.ToString();

    }

}

使用是显而易见的,因为它是一个静态类,只需调用IniFileManager。IniWriteValue用于读取section或IniFileManager。IniReadValue用于读取section。

通常,当您使用c#和. net框架创建应用程序时,您不会使用INI文件。更常见的方法是将设置存储在基于xml的配置文件或注册表中。 但是,如果您的软件与遗留应用程序共享设置,则可能更容易使用其配置文件,而不是将信息复制到其他地方。

. net框架不支持直接使用INI文件。但是,您可以使用带有平台调用服务(P/Invoke)的Windows API函数来写入和读取文件。在本链接中,我们创建了一个表示INI文件的类,并使用Windows API函数来操作它们。 请点击下面的链接。

读取和写入INI文件