读取 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
}
返回设置; }
这将为您完成:
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.</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;
}