原创 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 ...
随机推荐
- 161. One Edit Distance
题目: Given two strings S and T, determine if they are both one edit distance apart. 链接: http://leetco ...
- 【HDOJ】1204 糖果大战
题目本身不难.类似于dp.f(i)表示手中现有i颗糖果赢的概率,则下一局赢的概率是p(1-q),下一局输的概率是q(1-p),下一句平手的概率是1-p(1-q)-q(1-p),平手包括两人均答对或答错 ...
- 7 个面向Web开发者的实用CSS3教程推荐
通过CSS来创建精细.复杂的效果,成为了Web前端开发的未来趋势.世界各地的设计师认为CSS3是一项非常具有潜力的技术,未来将会创造更多不可思议的美妙设计. 本文为Web开发者带来了一些与CSS3相关 ...
- BZOJ3166: [Heoi2013]Alo
3166: [Heoi2013]Alo Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 394 Solved: 204[Submit][Status] ...
- CodeForces 400
A - Inna and Choose Options Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d &a ...
- 【转】Ubuntu下配置支持Windows访问的samba共享
原文网址:http://blog.csdn.net/i_chips/article/details/19191957 一.安装Ubuntu samba服务器 $ sudo apt-get instal ...
- useradd adduser linux创建用户、设置密码、修改用户、删除用户
创建用户.设置密码.修改用户.删除用户: useradd testuser 创建用户testuser passwd testuser 给已创建的用户testuser设置密码 说明:新创建的用户会在/h ...
- mat之一--eclipse安装Memory Analyzer
工欲善其事必先利其器,先开始更新下eclipse,顺便装下工具软件.那么简要的写写怎么从头安装Memory Analyzer Memory Analyzer (Eclipse MAT)是一个跨平台的开 ...
- 在windows下创建基于github的hexo静态博客
最近边上的人都突然买起了域名搭起了个人网站,渣渣的我介于期末没事干也跟风搭了个静态博客.虽说博客基本不更新T T,嘛嘛回归正题. 首先准备工作: 1)安装nodejs 2)安装msysgit(虽然现在 ...
- [TVYJ1096]数字组合
时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 在N个数中找出其和为M的若干个数.先读入正整数N(1<N<100)和M(1<M<100 ...