Чтение / запись файла INI - PullRequest
       27

Чтение / запись файла INI

239 голосов
/ 20 октября 2008

Существует ли какой-либо класс в .NET Framework, который может читать / записывать стандартные файлы .ini:

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

В Delphi есть компонент TIniFile, и я хочу знать, есть ли что-нибудь подобное для C #?

Ответы [ 16 ]

2 голосов
/ 14 октября 2016

Вот моя собственная версия с использованием регулярных выражений. В этом коде предполагается, что каждое имя раздела уникально - если, однако, это не так - имеет смысл заменить словарь списком. Эта функция поддерживает комментирование файла .ini, начиная с ';' персонаж. Секция начинается нормально [section], и пары ключ-значение также обычно идут как «ключ = значение». То же предположение, что и для разделов - имя ключа уникально.

/// <summary>
/// Loads .ini file into dictionary.
/// </summary>
public static Dictionary<String, Dictionary<String, String>> loadIni(String file)
{
    Dictionary<String, Dictionary<String, String>> d = new Dictionary<string, Dictionary<string, string>>();

    String ini = File.ReadAllText(file);

    // Remove comments, preserve linefeeds, if end-user needs to count line number.
    ini = Regex.Replace(ini, @"^\s*;.*$", "", RegexOptions.Multiline);

    // Pick up all lines from first section to another section
    foreach (Match m in Regex.Matches(ini, "(^|[\r\n])\\[([^\r\n]*)\\][\r\n]+(.*?)(\\[([^\r\n]*)\\][\r\n]+|$)", RegexOptions.Singleline))
    {
        String sectionName = m.Groups[2].Value;
        Dictionary<String, String> lines = new Dictionary<String, String>();

        // Pick up "key = value" kind of syntax.
        foreach (Match l in Regex.Matches(ini, @"^\s*(.*?)\s*=\s*(.*?)\s*$", RegexOptions.Multiline))
        {
            String key = l.Groups[1].Value;
            String value = l.Groups[2].Value;

            // Open up quotation if any.
            value = Regex.Replace(value, "^\"(.*)\"$", "$1");

            if (!lines.ContainsKey(key))
                lines[key] = value;
        }

        if (!d.ContainsKey(sectionName))
            d[sectionName] = lines;
    }

    return d;
}
1 голос
/ 06 июля 2017

Если вам нужен только доступ на чтение, а не доступ на запись, и вы используете Microsoft.Extensions.Confiuration (поставляется по умолчанию в комплекте с ASP.NET Core, но работает и с обычными программами), вы можете использовать пакет NuGet Microsoft.Extensions.Configuration.Ini для импорта INI-файлов в настройки вашей конфигурации.

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddIniFile("SomeConfig.ini", optional: false);
    Configuration = builder.Build();
}
1 голос
/ 12 июня 2016

Если вам нужен простой читатель без разделов и любых других библиотек, вот простое решение:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tool
{
    public class Config
    {
        Dictionary <string, string> values;
        public Config (string path)
        {
            values = File.ReadLines(path)
            .Where(line => (!String.IsNullOrWhiteSpace(line) && !line.StartsWith("#")))
            .Select(line => line.Split(new char[] { '=' }, 2, 0))
            .ToDictionary(parts => parts[0].Trim(), parts => parts.Length>1?parts[1].Trim():null);
        }
        public string Value (string name, string value=null)
        {
            if (values!=null && values.ContainsKey(name))
            {
                return values[name];
            }
            return value;
        }
    }
}

Образец использования:

    file = new Tool.Config (Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\config.ini");
    command = file.Value ("command");
    action = file.Value ("action");
    string value;
    //second parameter is default value if no key found with this name
    value = file.Value("debug","true");
    this.debug = (value.ToLower()=="true" || value== "1");
    value = file.Value("plain", "false");
    this.plain = (value.ToLower() == "true" || value == "1");

Между тем содержимое файла конфигурации (как вы видите, поддерживает символ # для комментария к строке):

#command to run
command = php

#default script
action = index.php

#debug mode
#debug = true

#plain text mode
#plain = false

#icon = favico.ico
0 голосов
/ 01 октября 2018

Вот мой класс, работает как шарм:

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 для чтения раздела или IniFileManager.IniReadValue для чтения раздела.

0 голосов
/ 13 января 2016

Вы должны читать и записывать данные из файлов XML, так как вы можете сохранить весь объект в XML, а также заполнить объект из сохраненного XML. Лучше легко манипулировать объектами.

Вот как это сделать: Запись данных объекта в файл XML: https://msdn.microsoft.com/en-us/library/ms172873.aspx Чтение данных объекта из файла XML: https://msdn.microsoft.com/en-us/library/ms172872.aspx

...