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

时间:2013-09-09 14:04:09

标签: c# .net io

我有一个关于阅读ini文件的问题, 我需要阅读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

我必须阅读该行的前两个字符,所以在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
                           }

返回设置;                             }

5 个答案:

答案 0 :(得分:2)

这将为你做到:

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。这实际上取决于真正的域名需求,但这不会是一个很大的修改。

您当然可以修改它以满足您需要的任何其他类型的查询的需求。

答案 1 :(得分:1)

  

我知道我使用INI文件不正确,但这很容易   方式。

我认为这不是最简单的方法,尝试已经实施的方法: GetPrivateProfileSection

有两个有用的Windows API来读/写ini文件:

GetPrivateProfileString

WriteProfileString

检查出来!

答案 2 :(得分:1)

                   `   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);
    }`
}
}

答案 3 :(得分:0)

您可以使用读取INI文件的第三个= party类:

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

答案 4 :(得分:0)

正如其他人所说,保存设置比伪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;

}