【问题标题】:Read specific part of an INI file C#读取 INI 文件 C# 的特定部分
【发布时间】:2013-09-13 01:14:01
【问题描述】:

我有一个关于读取 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

我必须阅读该行的前 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
                           }

返回设置; }

【问题讨论】:

  • 我强烈建议考虑迁移到基于 app.config 的设置
  • @DavidBrabant 我必须让它在我自己的程序中工作,或者有可用的资源
  • 天啊..INI 文件。自 Windows 95 以来我就再也没有见过它们。那就像...... 18 年前?
  • 哈哈,我知道它已经过时了,但它可以是一种无需数据库即可保存属性的简单方法。

标签: c# .net io


【解决方案1】:

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

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

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

GetPrivateProfileString

WriteProfileString

检查一下!

【讨论】:

  • 就像我说的,我只需要读取行的特定部分,并且我已经可以读取和写入文件。但我必须知道如何才能读取一行中的第一个字符。
【解决方案2】:

您可以使用读取 INI 文件的第三方类:

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

【讨论】:

  • 1966 年? ini文件那么旧吗? :)
  • @ya23 嗯,不……文章其实是2002年的,链接里的1966号跟年份没有关系……
  • 我知道,因此在我的评论中使用“:)”。只是一个(可怜的)玩笑尝试。
【解决方案3】:

这将为您完成:

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 =&gt; !line.StartsWith("[ACR]")) 会一直跳到它找到它想要的部分。
  • .Skip(1) 跳过该行,因为我们真的想读取值。
  • .TakeWhile(line =&gt; !string.IsNullOrEmpty(line)) 一直读取直到找到一个空行。
  • .Select(line =&gt; new... 将每一行的值选择为匿名类型。

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

这种方法的另一个好处是它可以延迟执行,因此如果您不必阅读整个文件即可找到它不会找到的部分。

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

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

【讨论】:

  • 它不起作用 :( 因为整个 ACR 部分将不再显示。
  • 我实现了你的一段代码并对其进行了测试,但是当我启动程序时,它不会从 ini 文件中读取整个 [ACR] 部分,因此文本框是空的。
  • @user2721466:INI 文件看起来像您示例中的那个吗?因为那是我从中提取 INI 文件进行测试的地方。当我运行它时,我会在一个可枚举的键值对中获得整个 [ACR] 部分。
  • 是的ini文件是一样的,也许你可以使用主窗体的代码
  • @user2721466,您将无法将我的解决方案复制并粘贴到您的代码中。我已经给出了一个有效的查询。如果您不想返回键值对,则只需将Select 更改为Select() 并循环遍历结果以设置文本框的值。
【解决方案4】:

正如其他人所说,有比伪 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;

}

【讨论】:

    【解决方案5】:
                       `   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);
        }`
    }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-03-30
      • 1970-01-01
      • 1970-01-01
      • 2011-05-30
      • 2015-05-02
      • 1970-01-01
      • 2012-03-29
      • 1970-01-01
      • 2014-05-10
      相关资源
      最近更新 更多