读取 INI 文件 C# 的特定部分

本文关键字:定部 INI 文件 读取 | 更新日期: 2023-09-27 18:30:45

>我有一个关于读取 ini 文件的问题,我需要读取 im 使用的 ini 文件的特定部分,但无法弄清楚如何做到这一点,我已经可以从 ini 文件读取和写入,但我需要读取特定部分。

这是我的INI文件:

[Settings]
[ACR]
11: Start Removal =90 // ms
12: Removal Time  =20 // commentary
13: Removal Delay =2.1 // commentary
[Cleaning]
21: Dur. Cleaning =90 //commentary
22: Time valve on =30  //commentary
23: Time valve off =15    //commentary
[Calibrate]
31: Content left =100//commentary
32: Calibrate left =--.-//commentary
33: Content right =100//commentary
34: Calibrate right =25.6//commentary
[Conductivity]
41: Factor left =500//commentary
42: Offset left =220//commentary
43: Factor right =500//commentary
44: Offset right =40//commentary
45: Level left =85//commentary
46: Level right =85//commentary
[General]
51: Type of valve =5//commentary
52: Indicator =2//commentary
53: Inverse output =0//commentary
54: Restart time =30//commentary
55: Water time =0//commentary
56: Gate delay =10//commentary
[Pulsation]
61: Pulsation p/m =60//commentary
62: S/r ratio front =55//commentary
63: S/r ratio back =60//commentary
64: Stimulation p/m =200//commentary
65: S/r stim front =30//commentary
66: S/r stim back =30//commentary
67: Stimulation dur =20//commentary

我必须阅读该行的前 2 个字符,所以在 ACR 部分下我需要阅读 10、11 和 12。 通过部分清洁,我必须读取 21、22、23 等。

这是我到目前为止的代码:

using System;
using System.Windows.Forms;
using Idento.Common.Utilities;
using Milk_Units;
namespace Milk_Units
{
    public class SettingsIniFile
    {
        private const String FileNameCustom = "Data''Custom.ini";//Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), );
        private const String FileNameDefault = "Data''Default.ini";//Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), );

        public Settings LoadSettings(bool defaults = false)
        {
            String fileName = defaults ? FileNameDefault : FileNameCustom;
            StringList input = new StringList().FromFile(fileName);
            //Settings settings = null;
            Settings settings = new Settings();
            foreach (var item in input)
            {
                String line = item.Trim();
                if (line.StartsWith("[") && line.EndsWith("]"))
                    continue;
                int index = line.IndexOf('=');
                if (index < 0)
                    continue;
                String key = line.Substring(0, index).Trim();
                String value = line.Substring(index + 1).Trim();
                String comment = "";
                index = value.IndexOf("//");
                if (index > -1)
                {
                    comment = value.Substring(index).Trim();
                    value = value.Substring(0, index).Trim();
                }
                // ACR
                if (Utils.EqualsIgnoreCase(key, "10: Start Removal"))
                    settings.AcrStartRemoval = value;
                else if (Utils.EqualsIgnoreCase(key, "11: Removal Time"))
                    settings.AcrRemovalTime = value;
                else if (Utils.EqualsIgnoreCase(key, "12: Removal Delay"))
                    settings.AcrRemovalDelay = value;
                // CLEANING
                else if (Utils.EqualsIgnoreCase(key, "21: Dur. Cleaning"))
                    settings.CleanDurCleaning = value;
                else if (Utils.EqualsIgnoreCase(key, "22: Time valve on"))
                    settings.CleanTimeValveOn = value;
                else if (Utils.EqualsIgnoreCase(key, "23: Time valve off"))
                    settings.CleanTimeValveOff = value;
                //CALIBRATE
                else if (Utils.EqualsIgnoreCase(key, "31: Content left"))
                    settings.CalibrateContentLeft = value;
                else if (Utils.EqualsIgnoreCase(key, "32: Calibrate left"))
                    settings.CalibrateCalibrateLeft = value;
                else if (Utils.EqualsIgnoreCase(key, "33: Content right"))
                    settings.CalibrateContentRight = value;
                else if (Utils.EqualsIgnoreCase(key, "34: Calibrate right"))
                    settings.CalibrateCalibrateRight = value;
                //CONDUCTIVITY
                else if (Utils.EqualsIgnoreCase(key, "41: Factor left"))
                    settings.ConductFactorLeft = value;
                else if (Utils.EqualsIgnoreCase(key, "42: Offset left"))
                    settings.ConductOffsetleft = value;
                else if (Utils.EqualsIgnoreCase(key, "43: Factor right"))
                    settings.ConductFactorRight = value;
                else if (Utils.EqualsIgnoreCase(key, "44: Offset right"))
                    settings.ConductOffsetRight = value;
                else if (Utils.EqualsIgnoreCase(key, "45: Level left"))
                    settings.ConductLevelLeft = value;
                else if (Utils.EqualsIgnoreCase(key, "46: Level right"))
                    settings.ConductLevelRight = value;
                //GENERAL
                else if (Utils.EqualsIgnoreCase(key, "51: Type of valve"))
                    settings.GeneralTypeOfValve = value;
                else if (Utils.EqualsIgnoreCase(key, "52: Indicator"))
                    settings.GeneralIndicator = value;
                else if (Utils.EqualsIgnoreCase(key, "53: Inverse output"))
                    settings.GeneralInverseOutput = value;
                else if (Utils.EqualsIgnoreCase(key, "54: Restart time"))
                    settings.GeneralRestartTime = value;
                else if (Utils.EqualsIgnoreCase(key, "55: Water time"))
                    settings.GeneralWaterTime = value;
                else if (Utils.EqualsIgnoreCase(key, "56: Gate delay"))
                    settings.GeneralGateDelay = value;
                //PULSATION
                else if (Utils.EqualsIgnoreCase(key, "61: Pulsation p/m"))
                    settings.PulsationPulsationPm = value;
                else if (Utils.EqualsIgnoreCase(key, "62: S/r ratio front"))
                    settings.PulsationSrRatioFront = value;
                else if (Utils.EqualsIgnoreCase(key, "63: S/r ratio back"))
                    settings.PulsationSrRatioBack = value;
                else if (Utils.EqualsIgnoreCase(key, "64: Stimulation p/m"))
                    settings.PulsationStimulationPm = value;
                else if (Utils.EqualsIgnoreCase(key, "65: S/r stim front"))
                    settings.PulsationSrStimFront = value;
                else if (Utils.EqualsIgnoreCase(key, "66: S/r stim back"))
                    settings.PulsationSrStimBack = value;
                else if (Utils.EqualsIgnoreCase(key, "67: Stimulation dur"))
                    settings.PulsationStimulationDur = value;

            }
            return settings;
        }

提前感谢,我知道我没有正确使用 INI 文件,但这是最简单的方法。

Awnser 谢谢 Neoistheone 的帮助

      foreach (var item in input)
                    {
                        String line = item.Trim();
                        if (line.StartsWith("[") && line.EndsWith("]"))
                            continue;
                        int index = line.IndexOf('=');
                        if (index < 0)
                            continue;
                        String key = line.Substring(0, index).Trim();
                        String ID = line.Substring(0, line.IndexOf(':'));
                        String value = line.Substring(index + 1).Trim();
                        //String comment = "";
                        index = value.IndexOf("//");
                        if (index > -1)
                        {
                         ID = line.Substring(0, line.IndexOf(':'));
                            //comment = value.Substring(index).Trim();
                            value = value.Substring(0, index).Trim();
                        }

                        // ACR
                        if (Utils.EqualsIgnoreCase(key, "11: Start Removal"))
                           {
                           settings.AcrStartRemoval11 = value;
                           _settings.AcrId11.ID
                           }

返回设置; }

读取 INI 文件 C# 的特定部分

这将为您完成:

var vals = File.ReadLines("C:''TEMP''test.ini")
    .SkipWhile(line => !line.StartsWith("[ACR]"))
    .Skip(1)
    .TakeWhile(line => !string.IsNullOrEmpty(line))
    .Select(line => new
    {
        Key = line.Substring(0, line.IndexOf(':')),
        Value = line.Substring(line.IndexOf(':') + 2)
    });

解释

  • .SkipWhile(line => !line.StartsWith("[ACR]"))跳过,直到找到所需的部分。
  • .Skip(1)跳过这一行,因为我们真的想读取值。
  • .TakeWhile(line => !string.IsNullOrEmpty(line))读取,直到找到空行。
  • .Select(line => new...将每行的值选择为匿名类型。

因此,只需传入正确的部分即可获得您想要的任何部分。

这种方法的另一个好处是它是延迟执行的,因此如果您不必读取整个文件来查找该部分,它就不会。

现在,在您的情况下,您可能需要稍微按摩一下,以确保它不会读取行尾的评论,例如通过更改最后一个Substring。这实际上取决于真正的域需求,但这不会是一个大的修改。

当然,您也可以修改此设置以满足所需的任何其他类型的查询的需求。

我知道我没有正确使用 INI 文件,但这是最简单的 道路。

我认为这不是最简单的方法,请尝试已经实现的内容:获取私人配置文件部分。

有 2 个有用的窗口 API 来读取/写入 ini 文件:

GetPrivateProfileString

WriteProfileString

看看他们!

                   `   namespace TeknoModding
{
    using System;
    using System.IO;
    using System.Collections;
public class IniFile
{
    private readonly Hashtable _keyPairs = new Hashtable();
    private readonly 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.&lt;/param>
    public IniParser(String iniPath)
    {
        TextReader iniFile = null;
        String strLine = null;
        String currentRoot = null;
        String[] keyPair = null;
        this._iniFilePath = iniPath;
        if(File.Exists(iniPath))
        {
            try
            {
                iniFile = new StreamReader(iniPath);
                strLine = iniFile.ReadLine();
                while (strLine != null)
                {
                    strLine = strLine.Trim();
                   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];
                          this._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)
    {
        try
        {
        SectionPair sectionPair;
        sectionPair.Section = sectionName;
        sectionPair.Key = settingName;
        return (String)this._keyPairs[sectionPair];
        }
        catch (Exception)
        {
            return string.Empty;
        }
    }
    /// <summary>
    /// Enumerates alllines for given section.
    /// </summary>
    /// <param name="sectionName">Section to enum.</param>;
    public string[] EnumSection(string sectionName)
    {
        ArrayList tmpArray = new ArrayList();
        foreach (SectionPair pair in this._keyPairs.Keys)
        {
            if (pair.Section == sectionName)
                tmpArray.Add(pair.Key);
        }
        return (String[])tmpArray.ToArray(typeof(String));
    }
    /// <summary>
    /// Adds or replaces a setting to the tableto 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;
        sectionPair.Key = settingName;
        if(this._keyPairs.ContainsKey(sectionPair))
            this._keyPairs.Remove(sectionPair);
        this._keyPairs.Add(sectionPair, settingValue);
    }
    /// <summary>
    /// Adds or replaces a setting to the tableto be saved with a nullvalue.
    /// </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;
        sectionPair.Key = settingName;
        if(this._keyPairs.ContainsKey(sectionPair))
            this._keyPairs.Remove(sectionPair);
    }
    /// <summary>
    /// Save settingsto 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 this._keyPairs.Keys)
        {
            if (!sections.Contains(sectionPair.Section))
                sections.Add(sectionPair.Section);
        }
        foreach (string section in sections)
        {
            strToSave += ("[" +section + "]'r'n");
            foreach (SectionPair sectionPair in this._keyPairs.Keys)
            {
                if (sectionPair.Section == section)
                {
                   tmpValue = (String)this._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 settingsback to ini file.
    /// </summary>
    public void SaveSettings()
    {
        SaveSettings(this._iniFilePath);
    }`
}
}
您可以使用读取

INI 文件的第三方=派对类:

http://www.codeproject.com/Articles/1966/An-INI-file-handling-class-using-C

正如其他人所说,有比伪 INI 文件更好的方法来保存您的设置,但如果必须,您可以使用正则表达式来解析您的字符串:

void Main()
{
    string line1 = "[ACR]";
    string line2 = "53: Inverse output =0.3//commentary";
    var a = Regex.Match(line1,@"^'[(.*)']").Groups;
    var b = Regex.Match(line2,@"^('d'd):'s*(.*)'s*=(.*)//(.*)").Groups;
    string sectionName = a[1].Value;
    string number = b[1].Value;
    string setting = b[2].Value;
    string value = b[3].Value;
    string comment = b[4].Value;
}