我有一个关于阅读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
}
返回设置; }
答案 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文件:
检查出来!
答案 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.</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;
}