当前位置: 首页 > 工具软件 > ini-parser > 使用案例 >

C#--ini-parser解析库

林修雅
2023-12-01

目录

基础应用

INI文件结构

细节

存取资料

直接访问

添加或删除节或键

保存文件

示例中使用的INI文件的内容

配置解析器行为

自定义解析器算法—仅供参考

附件:获取ini-parser


基础应用

此页面将显示代码示例,这些示例将帮助您使用此解析器读取INI文件的内容。请参阅配置页面以了解如何在解析文件时更改。

INI文件结构

各个部分的INI文件const,每个定义一个唯一的键,并为每个键分配一个唯一的值。
节被声明为包含在方括号中的唯一单词。方括号内的空格将被忽略,但必须使用唯一的单词([sampleSection])定义该部分

在部分中,我们可以定义具有唯一值的键。键在同一部分中必须唯一,但在不同部分中可以具有相同的键名称。使用等号分配键(键=值)

另外,我们可以使用分号(;)定义单行注释。

因此,可以这样编写一个简单的INI文件:

[ section ]
;comment
key = value

细节

所有代码示例均期望以下using子句:

using IniParser;
using IniParser.Model;

首先要做的是创建一个INI解析器的实例

//创建一个ini文件解析器的实例
var parser = new IniDataParser();

 ini解析器只能使用字符串中的INI数据,因此,如果要解析文件或获取ini数据,则可以使用提供的一些帮助器类(FileIniParser或StreamIniParser),或者仅从任何源读取ini数据源自己作为字符串,然后使用IniDataParser.Parse方法。

// 使用FileIniDataParser实例轻松解析或持久保存ini文件。
var parser = new FileIniDataParser();

现在,我们可以使用ReadFile解析器对象中的Method获取INI数据。这将返回一个新IniData实例,其中包含从INI文件解析的所有数据:

var parser = new FileIniDataParser();

// 这将加载INI文件,读取失败中包含的数据,并解析该数据
IniData data = parser.ReadFile("TestIniFile.ini");

ini文件中的所有节都由表示SectionDataCollection,这不过是SectionData实例的集合。每个SectionData字符串都包含一个带有该部分名称的字符串,一个包含与该部分关联的注释的字符串列表以及该部分中的键列表。该列表由实例KeyDataCollection集合表示KeyData。

存取资料

由于实现了DataCollection类型,IEnumerator因此可以使用for each循环来迭代数据:

//通过所有的段迭代
foreach (SectionData section in data.Sections)
{
   Console.WriteLine("[" + section.Name + "]");
   
   //遍历当前节中的所有键以打印值
   foreach(KeyData key in section.Keys)
      Console.WriteLine(key.Name + " = " + key.Value);
}

直接访问

如果知道所需部分的名称和键,则可以直接访问数据

//此行从“ GeneralConfiguration”部分获取SectionData 
KeyDataCollection keyCol = data["GeneralConfiguration"];

//此行从“generalconfiguration”部分定义的键“setupdate”获取keydata
string directValue = keyCol["setUpdate"];

//但是一口气获取值更容易:
directValue = data["GeneralConfiguration"]["setUpdate"];

解析的数据也可以轻松地修改:

data["GeneralConfiguration"]["setUpdate"] = "150";

添加或删除节或键

您可以通过编程方式添加或删除部分和/或键/值对:

var parser = new FileIniDataParser();
IniData data = parser.ReadFile("TestIniFile.ini");

//添加一个新部分和一些键
data.Sections.AddSection("newSection");
data["newSection"].AddKey("newKey1", "value1");
data["newSection"].AddKey("newKey2", "value5");

//删除最后一个键
data["newSection"].RemoveKey("newKey2");

//从文件中删除“Users”部分以及与之关联的所有键和注释
data.Sections.RemoveSection("Users");

保存文件

如果您对已解析的数据进行了修改,或者创建了一个新IniData实例并填充了它,则可能希望将数据保存到文件中。为此,只需使用FileIniDataParser实例中的“ SaveFile”方法:

var parser = new FileIniDataParser();

//获取数据
IniData parsedINIDataToBeSaved;

//保存文件
parser.WriteFile("newINIfile.ini", parsedINIDataToBeSaved);

您也可以使用IniData.ToString()方法创建包含ini文件内容的字符串。

  IniData data = new IniData();

  data["Section1"]["key1"] = "value1";

  Console.WriteLine(data.ToString());

示例中使用的INI文件的内容

该示例中使用的INI文件包含以下信息:

;This section provides the general configuration of the application
[GeneralConfiguration] 

;Update rate in msecs
setUpdate = 100

;Maximum errors before quitting
setMaxErrors = 2

[UI]
fullscreen = false

;Users allowed to access the system
;format: user = pass
[Users]
ricky = rickypass
patty = pattypass

配置解析器行为

由于INI格式没有标准化,因此Ini Parser 2.0版引入了一种更简单的方法来定制INI文件的解析方式,从而提供了一种处理所有不同格式变化的简便方法。

使用IniParserConfiguration对象,您可以重新定义解析ini文件时解析器将如何处理特殊项目。例如,您可以重新定义用作注释的字符,而不是使用字符’;’。(默认),您可以设置以’#'字符开头的行为注释。

您还可以定义解析器应如何处理错误(例如,抛出异常或仅返回null值),或者在解析具有“奇怪”格式的文件时应具有的自由度或保守度。

创建的实例时,IniDataParser您可以传递配置对象。配置对象跟随。IIniParserConfiguration接口。如果您不提供默认实例,则将使用默认实例。

您可以使用IniDataParser实例中的Configuration属性来访问和修改解析器的配置。有关示例,请参见parse_ini_string_with_custom_configuration测试。

如果您发现自己在许多地方都使用了自定义配置,则最好使用所需的行为来创建自定义配置对象。只需创建一个派生类BaseIniParserConfiguration并在构造函数中设置自定义属性的值即可。这是DefaultIniParserConfiguration实际使用的方法。

这是IIniParserConfiguration接口规范中定义的配置选项的列表:

类型描述名称
boolAllowCreateSectionsOnFly如果为true,如果您尝试将键添加到不存在的部分,则该部分将自动动态创建,而不会引发异常。默认为false。
boolAllowDuplicateKeys如果在某节中找到重复的键,这是false解析器将因错误而停止。如果它是true重复键的值,则将是分配给键的最后一个值。默认为false。
boolAllowDuplicateSections如果设置为,false并且找到重复的部分,则解析器将停止并显示错误。如果设置为true,则文件中允许使用重复的节,但是将仅SectionData在IniData.Sections集合中创建一个元素,从而有效地合并相同名称的重复节中的所有键。默认为false。
boolAllowKeysWithoutSection允许文件中有不属于任何部分的键。即允许在定义部分之前定义键。如果设置为,false并且定义了没有节的键,则解析器将因错误而停止。默认为true。
stringAssigmentSpacer设置KeyValuesAssignmentString之前和之后的字符串。默认为字符串“”
RegexCommentRegex用于匹配注释字符串的正则表达式
charCommentString设置将定义注释开头的字符串。注释从注释字符到行尾。默认为“#”
charKeyValueAssigmentString设置将值的分配与键分开的字符串。默认为“ =”
boolOverrideDuplicateKeys仅适用,如果AllowDuplicateKeys是true。如果设置为true当解析器发现重复的键时,它将覆盖先前的值,因此该键将始终包含文件中读取的最后一个键的值。如果设置为false第一个读取的值,则保留该键,因此该键将始终包含文件中读取的第一个键的值。默认为false。
charSectionEndString设置定义节名结尾的字符串。默认为“]”
RegexrRegex用于匹配部分字符串的正则表达式
charSectionStartString设置定义节名称开头的字符串。默认为“ [”
boolSkipInvalidLines如果设置为true,则当解析器发现无效行时,它只会跳过该行,而不是ParseException在解析时抛出a 或返回null(如果由于将属性ThrowExceptionsOnError设置为false,则禁用了异常)。默认为false
boolThrowExceptionsOnError如果true发现错误,解析器将引发异常。如果false解析器将仅停止执行并返回一个null值作为结果。默认为true。
stringNewLineStr用作NewLine的字符串。仅在从IniData结构创建ini字符串时使用,使用IIniDataFormatter。例如,这允许在Windows上使用类unix的结尾字符串创建ini文件。默认值是用于执行此库的系统的正确的换行符/字符串。

如果需要细粒度的自定义进行解析,则可以从中创建派生类IniDataParser并覆盖某些方法。请参见修改解析器页面

自定义解析器算法—仅供参考

如果您需要对解析算法进行更细粒度的自定义,则可以从中创建派生类IniDataParser并覆盖控制解析操作的方法(例如,检查行是否为注释,段或键值的方法)作业等)

请注意,如果您只想更改解析的一些小方面(例如更改用于定义注释的字符),则可以为解析器创建自定义配置来节省时间。请参阅配置解析器行为页面以获取更多信息。

解析算法中的所有步骤都是使用受保护的方法执行的,因此可以在派生类中对其进行修改。这是[模板方法模式]的特例,其中提供了模板方法的默认实现。

这是可以在派生类中进行更改以修改解析器的方法的列表,该解析器的算法通过以下步骤工作:

  • 一次读取一行,丢弃空行(所有空白)并ProcessLine()为非空行调用方法
  • 提取注释(如果有)(LineContainsAComment()和ExtractComment()方法)
  • 如果该行是一个Section(LineMatchesASection()调用ProcessSection()以存储该段的名称
  • 如果该行是键/值对(LineMatchesAKeyValuePair()),则调用ProcessKeyValuePair()以存储键和值
  • 如果该行不是注释,节或键/值对,则无法解析该行,并导致跳过该行或引发异常,具体取决于配置。
/// <summary>
///     处理一行并解析在该行中找到的数据(可能有或可能没有注释的节或键/值对)
/// </summary>
/// <param name="currentLine">The string with the line to process</param>
protected void ProcessLine(string currentLine, IniData currentIniData)

 该方法首先提取注释,如果行

/// <summary>
///     检查给定字符串是否包含注释。
/// </summary>
/// <param name="line">
///     要检查的字符串。
/// </param>
/// <returns>
///     <c>true</c> 如果s中的任何子字符串是注释,则<c>false</c>否则。
/// </returns>
protected bool LineContainsAComment(string line)


/// <summary>
///    从字符串中移除注释(如果存在),并返回不带注释子字符串的字符串。
/// </summary>
/// <param name="line">
///    要从中删除注释的字符串。
/// </param>
/// <returns>
///     The string s without comments.
/// </returns>
protected string ExtractComment(string line)


/// <summary>
///     检查给定的字符串是否表示节定界符。
/// </summary>
/// <param name="line">
///     要检查的字符串。
/// </param>
/// <returns>
///     < c > true </ c >如果字符串表示一个节,否则返回< c > false </ c >。
/// </returns>
protected bool LineMatchesASection(string line)


/// <summary>
///     检查给定的字符串是否表示键/值对。
/// </summary>
/// <param name="line">
///     要检查的字符串。
/// </param>
/// <returns>
///     <c>true</c> 字符串是否表示一个键/值对, <c>false</c> 否则
/// </returns>
protected bool LineMatchesAKeyValuePair(string line)


/// <summary>
///     处理      包含ini节的字符串。
/// </summary>
/// <param name="line">
///     要处理的字符串
/// </param>
protected void ProcessSection(string line, IniData currentIniData)


/// <summary>
///     处理包含ini键/值对的字符串。
/// </summary>
/// <param name="line">
///     要处理的字符串
/// </param>
protected void ProcessKeyValuePair(string line, IniData currentIniData)


/// <summary>
///     提取包含键/值对的字符串的键部分
/// </summary>
/// <param name="s">    
///     要处理的字符串,其中包含键/值对
/// </param>
/// <returns>
///     所提取键的名称。
/// </returns>
protected string ExtractKey(string s)


/// <summary>
///    提取包含键/值对的字符串的值部分
/// </summary>
/// <param name="s">
///     要处理的字符串,其中包含键/值对
/// </param>
/// <returns>
///     提取值的名称。
/// </returns>
protected string ExtractValue(string s)

附件:获取ini-parser

 类似资料: