原创 C# 正则表达式 读写 Ini 文件
昨天遇到读ini文件的问题,我知道C#里没有提供相应的类,所有的.net配置都是xml方式存储的。
读取ini文件,很多人直接google一把,然后添加dll引用。介绍的比较详细的,如: C#如何读写和创建INI文件
那么,如果不引用api呢? 我想到了正则表达式,分别读取section与key value,然后再匹配。刚好网上有一个类似的文章 用正则表达式读取INI文件
看了下他的内容,然后再整理下思路,OK,我自己的Helper就出来了。
namespace goldli.Utility.Library
{
public interface IPosition
{
int Position { get; set; }
} public class IniKey : IPosition
{
public string Name { get; set; } public string Value { get; set; } public int Position { get; set; }
} public class IniSection : Collection<IniKey>, IPosition
{
/// <summary>
/// Section名称
/// </summary>
public string Name { get; set; } /// <summary>
/// section在文件里位置,用于与KeyValue对比
/// </summary>
public int Position { get; set; } public IniKey Add(string keyName)
{
var result = Find(keyName);
if (result == null)
{
var key = new IniKey{Name = keyName};
Add(key);
}
return result;
} public void Remove(string keyName)
{
var key = Find(keyName);
if (key == null) return;
Remove(key);
} public override IniKey Find(object value)
{
var keyName = value as string;
if(string.IsNullOrEmpty(keyName)) throw new ArgumentNullException("value");
IniKey result = null;
Lock();
foreach (IniKey key in List)
{
if (!Tools.IsSameString(key.Name, keyName)) continue;
result = key;
break;
}
UnLock();
return result;
} /// <summary>
/// 判断一个key是否存在
/// </summary>
/// <param name="keyName"></param>
/// <returns></returns>
public bool KeyIsExist(string keyName)
{
return Find(keyName) != null;
} /// <summary>
/// 读取一个值
/// </summary>
/// <param name="keyName"></param>
/// <returns></returns>
public string ReadValue(string keyName)
{
var key = Find(keyName);
return key != null ? key.Value : null;
} /// <summary>
/// 写入一个值
/// </summary>
/// <param name="keyName"></param>
/// <param name="value"></param>
public void WriteValue(string keyName,string value)
{
Add(keyName).Value = value;
}
} public class Sections :Collection<IniSection>
{
/// <summary>
/// 查找
/// </summary>
/// <param name="value">Section.Name</param>
/// <returns></returns>
public override IniSection Find(object value)
{
var sectionName = value as string;
if (string.IsNullOrEmpty(sectionName)) throw new ArgumentNullException("value");
IniSection result = null;
Lock();
foreach (IniSection section in List)
{
if (!Tools.IsSameString(section.Name,sectionName)) continue;
result = section;
break;
}
UnLock();
return result;
}
} /// <summary>
/// Ini文件读写类
/// </summary>
public class IniHelper
{
private IniKey[] _array;
private int _arrarIndex; private const string ExpSection = "(?<=\\[)\\w+(?=\\]\\r)"; /// <summary>
/// 注:你要保证键值对中值不为空,即使是空字符串也不行
/// </summary>
private const string ExpKeyValue = "^(?<key>(?!;).+?)\\s*=\\s*(?<value>.*(?=\\r))"; //ini文件
private readonly string _fileName; private void ExtractKeyValues(string data)
{
try
{
var regexObj = new Regex(ExpKeyValue, RegexOptions.Multiline);
var mc = regexObj.Matches(data);
if (mc.Count > 0)
{
_array = new IniKey[mc.Count];
for (var i = 0; i < mc.Count; i++)
{
var m = mc[i].Groups;
var key = new IniKey { Name = m[1].Value, Value = m[2].Value, Position = m[1].Index };
_array[i] = key;
}
}
else
{
throw new RankException("error when regex key values.");
}
}
catch (Exception ex)
{
Sections.Clear();
throw;
}
} private void ExtractSections(string data)
{
try
{
var regexObj = new Regex(ExpSection);
var matchResults = regexObj.Match(data);
while (matchResults.Success)
{
var g = matchResults.Groups[0];
var section = new IniSection { Name = g.Value, Position = g.Index };
Sections.Add(section);
matchResults = matchResults.NextMatch();
}
}
catch (Exception ex)
{
Sections.Clear();
throw;
}
} /// <summary>
/// 根据起始位置查找keyvalue
/// </summary>
/// <param name="section"></param>
/// <param name="next"></param>
private void FillSection(IniSection section,int next)
{
for (var i = _arrarIndex; i < _array.Length; i++)
{
var key = _array[i];
if ((section.Position < key.Position) && (key.Position < next))
{
section.Add(key);
_arrarIndex++;
}
else
break;
}
} private void FillSections()
{
_arrarIndex = 0;
for (var i = 0; i < Sections.Count; i++)
{
var section = Sections[i];
var next = int.MaxValue;
if ((i + 1) != Sections.Count)
next = Sections[i + 1].Position;
FillSection(section,next);
}
Array.Clear(_array,0,_array.Length);
} public IniHelper(string fileName)
{
_fileName = fileName;
Sections =new Sections();
} /// <summary>
/// 文件编码
/// </summary>
public Encoding FileEncoding { get; set; } /// <summary>
/// 加载文件
/// </summary>
public void Load()
{
var data = FileReadWriteHelper.Read(_fileName, FileEncoding.WebName);
if (string.IsNullOrEmpty(data)) throw new FileLoadException(_fileName);
ExtractSections(data);
ExtractKeyValues(data);
FillSections();
} /// <summary>
/// 保存文件
/// </summary>
public void Save(string fileName)
{
var iniBuilder = new StringBuilder();
foreach (IniSection section in Sections)
{
var aSection = string.Format("[{0}]\r\n", section.Name);
iniBuilder.Append(aSection);
foreach (IniKey key in section)
{
var aKeyValue = string.Format("{0}={1}\r\n", key.Name, key.Value);
iniBuilder.Append(aKeyValue);
}
iniBuilder.Append(Environment.NewLine);
}
FileReadWriteHelper.Write(fileName, iniBuilder.ToString(), FileEncoding.WebName);
} public IniSection Add(string sectionName)
{
var section = Sections.Find(sectionName);
if (section == null)
{
section = new IniSection {Name = sectionName};
Sections.Add(section);
}
return section;
} public void Add(IniSection section)
{
var tmp = Sections.Find(section.Name);
if (tmp == null)
Sections.Add(section);
} public void Remove(string sectionName)
{
var section = Sections.Find(sectionName);
if (section == null) return;
Sections.Remove(section);
} public void Remove(IniSection section)
{
var tmp = Sections.Find(section.Name);
if (tmp == null) return;
Sections.Remove(section);
} public Sections Sections { get; private set; }
}
}
使用示例
var ini = new IniHelper(@"i:\spring.ini");
ini.FileEncoding = Encoding.ASCII;
ini.Load();
textBox1.Clear();
foreach (IniSection section in ini.Sections)
{
extBox1.AppendText("[" + section.Name +"]\r\n");
foreach (IniKey key in section)
{
textBox1.AppendText(key.Name + " = " + key.Value + "\r\n");
}
}
哈哈,其实挺简单的。主要的问题是把正则写正确。
原创 C# 正则表达式 读写 Ini 文件的更多相关文章
- c# 利用动态库DllImport("kernel32")读写ini文件(提供Dmo下载)
c# 利用动态库DllImport("kernel32")读写ini文件 自从读了设计模式,真的会改变一个程序员的习惯.我觉得嘛,经验也可以从一个人的习惯看得出来,看他的代码编写习 ...
- VB读写INI文件的四个函数以及相关API详细说明
WritePrivateProfileString函数说明 来源:http://blog.csdn.net/wjb9921/article/details/2005000 在我们写的程序当中,总有一 ...
- C# 读写INI 文件
INI 格式: [Section1] KeyWord1 = Value1 KeyWord2 = Value2 ... [Section2] KeyWord3 = Value3 KeyWord4 = V ...
- WIN32读写INI文件方法
在程序中经常要用到设置或者其他少量数据的存盘,以便程序在下一次执行的时候可以使用,比如说保存本次程序执行时窗口的位置.大小.一些用户设置的 数据等等,在 Dos 下编程的时候,我们一般自己产生一个 ...
- 读写ini文件
C# 使用文件流来读写ini文件 背景 之前采用ini文件作为程序的配置文件,觉得这种结构简单明了,配置起来也挺方便.然后操作方式是通过WindowsAPI,然后再网上找到一个基于WindowsAPI ...
- 在 WinCe 平台读写 ini 文件
在上篇文章开发 windows mobile 上的今日插件时,我发现 wince 平台上不支持例如 GetPrivateProfileString 等相关 API 函数.在网络上我并没有找到令我满意的 ...
- Windows中读写ini文件
.ini 文件是Initialization File的缩写,即初始化文件,是windows的系统配置文件所采用的存储格式,来配置应用软件以实现不同用户的要求.配置文件有很多种如ini配置文件,XML ...
- C#中读写INI文件
C#中读写INI文件 c#的类没有直接提供对ini文件的操作支持,可以自己包装win api的WritePrivateProfileString和GetPrivateProfileString函数实现 ...
- Qt读写ini文件
一 背景 1 ini文件介绍 .ini 文件是Initialization File的缩写,即初始化文件. 除了windows现在很多其他操作系统下面的应用软件也有.ini文件,用来配置应用软件以实现 ...
- 【python-ini】python读写ini文件
[python-ini]python读写ini文件 本文实例讲述了Python读写ini文件的方法.分享给大家供大家参考.具体如下: 比如有一个文件update.ini,里面有这些内容: 1 2 ...
随机推荐
- linux 文件、文件夹的重命名命令
linux中没有重命名命令,一般用mv替代.如将test更名为testsmv test tests隐藏是mv test .test 说到文件的隐藏,linux下文件如果想隐藏起来只要重命名这个文件就可 ...
- C#的同步和异步调用方法
同步和异步大家都明白什么意思,在这里不多介绍了. namespace ConsoleTest { class Program { static void Main(string[] args) { C ...
- linux 系统获取网络ip, mask, gateway, dns信息小程序
net_util.c #define WIRED_DEV "eth0" #define WIRELESS_DEV ...
- TreeMap源码解析
1.TreeMap介绍 TreeMap是一个通过红黑树实现有序的key-value集合. TreeMap继承AbstractMap,也即实现了Map,它是一个Map集合 TreeMap实现了Navig ...
- CCR源码分析-CCR架构
CCR,并发与协调运行时(Concurrency and Coordination Runtime).从名字里我们就可以知道,这个东东是用来简化并发程序设计的.为何要并发呢?因为我们有多个任务需要处理 ...
- modsecookie
Cookie parsing added添加cookie解析 现在你可以使用新的可选的过滤器变量(COOKIE_name, COOKIE_NAMES, COOKIE_VALUES)分析cookies. ...
- Ubuntu下添加Eclipse快捷方式
首先是在/usr/share/applications下创建eclipse.desktop文件 1. 创建并编辑eclipse.desktop sudo vim /usr/share/applicat ...
- 【libsvm学习】
参考: http://www.cnblogs.com/bigshuai/articles/2883256.html http://www.cnblogs.com/tornadomeet/archive ...
- 跟我学机器视觉-HALCON学习例程中文详解-开关引脚测量
跟我学机器视觉-HALCON学习例程中文详解-开关引脚测量 This example program demonstrates the basic usage of a measure object. ...
- hive的安装步骤
在node2里安装一下hive1.2.1,步骤如下: 1.解压hive的安装包 2.改变目录:mv apache-hive-1.2.1-bin /home/install/hive-1.2 3.vi ...