在应用程序中频繁地读取或写入INI文件可能会导致性能问题,因为标准的读取和写入函数会在每次调用时加载整个文件。为了解决这个问题,可以创建一个类来在内存中管理INI文件数据。这个类在初始化时加载INI文件,使用正则表达式解析数据,并使用字典来管理节名和数据。
这个类不使用传统的INI文件读取或写入方法。它在初始化时加载INI文件,使用正则表达式来解析数据,并使用字典来管理节名和数据。
在C#中,可以使用正则表达式来移除空行和解析INI数据。以下是两个静态只读的正则表达式:
static readonly Regex regRemoveEmptyLines = new Regex(
@"(\s*;[\d\D]*?\r?\n)+|\r?\n(\s*\r?\n)*",
RegexOptions.Multiline | RegexOptions.Compiled
);
static readonly Regex regParseIniData = new Regex(
@"(?^\s*\[(?[^\]]+)?\]\s*$)|(?^\s*(?[^(\s*\=\s*)]+)?\s*\=\s*(?[\dD]*)$)",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace
);
使用字典来存储节名和数据集合:
Dictionary data = new Dictionary();
以下是如何使用这个类的示例:
创建一个空的INI文档,可以动态添加节、键和值,并随时保存。
TA_INIDocument ini = new TA_INIDocument();
初始化一个INI文件,可以随时更改其数据并保存。
TA_INIDocument ini = new TA_INIDocument("C:\\sample.ini");
使用特定编码初始化INI文件。有时INI文件可能包含Unicode数据。
TA_INIDocument ini = new TA_INIDocument("C:\\sample.ini", Encoding.Unicode);
从流初始化INI数据。
Stream iniStream;
TA_INIDocument ini = new TA_INIDocument(iniStream);
从流初始化INI数据,并指定编码。
Stream iniStream;
TA_INIDocument ini = new TA_INIDocument(iniStream, Encoding.Unicode);
获取定义节的键值集合。
NameValueCollection keysAndValues = iniDoc["sectionName"];
获取定义键和节的字符串值。
string value = iniDoc["sectionName"]["keyName"];
string value = iniDoc["sectionName", "keyName"];
设置定义键的字符串值。
iniDoc["sectionName"]["keyName"] = "newValue";
iniDoc["sectionName", "keyName"] = "newValue";
获取和设置定义键和节的对象值。
object value = iniDoc["sectionName", "keyName", typeof(Int32)];
iniDoc["sectionName", "keyName", typeof(Rectangle)] = new Rectangle(0, 0, 200, 300);
除了字符串之外,还可以获取和设置其他类型的值,前提是这些类型具有TypeConverterAttribute。
bool bValue = iniDoc.GetBoolean("sectionName", "keyName");
bool bValue = iniDoc.GetBoolean("sectionName", "keyName", true);
iniDoc.SetValue("sectionName", "keyName", bValue);
DateTime dtValue = iniDoc.GetDateTime("sectionName", "keyName");
DateTime dtValue = iniDoc.GetDateTime("sectionName", "keyName", DateTime.MaxValue);
iniDoc.SetValue("sectionName", "keyName", dtValue);
Rectangle rtValue = iniDoc.GetValue("sectionName", "keyName");
Rectangle rtValue = iniDoc.GetValue("sectionName", "keyName", Rectangle.Empty);
iniDoc.SetValue("sectionName", "keyName", rtValue);
以下是一些辅助属性和函数:
TA_INIDocument iniDoc;
string[] sectionNames = iniDoc.SectionNames;
string[] keyNames = iniDoc.KeyNames("sectionName");
string[] allValues = iniDoc.SectionValues("sectionName");
if (iniDoc.HasSection("sectionName"))
Application.DoEvents();
if (iniDoc.HasKey("sectionName", "keyName"))
Application.DoEvents();
TA_INIDocument iniDoc;
Stream iniStream;
iniDoc.Save(iniStream);
iniDoc.Save(iniStream, Encoding.Unicode);
iniDoc.Save("C:\\sample.ini");
iniDoc.Save("C:\\sample.ini", Encoding.Unicode);