/*
* INI文件说明:
* INI是Initialization头三个字母的缩写;其后缀名也不一定是".ini"也可以是".cfg",".conf ”或者是".txt"
*
* INI文件由节、键、值组成
* 节
* [section]
* 参数(键=值)
* name=value
* 注解
* 注解使用分号表示(;)。在分号后面的文字,直到该行结尾都全部为注解。
*
* NI文件的格式很简单,最基本的三个要素是:parameters,sections和comments。
*
* 什么是parameters?
* INI所包含的最基本的“元素”就是parameter;每一个parameter都有一个name和一个value,
* name和value是由等号“=”隔开。name在等号的左边。
* 如:
* name = value
*
* 什么是sections?
* 所有的parameters都是以sections为单位结合在一起的。所有的section名称都是独占一行,
* 并且sections名字都被方括号包围着。在section声明后的所有parameters都是属于该section。
* 对于一个section没有明显的结束标志符,一个section的开始就是上一个section的结束,
* 或者是end of the file。Sections一般情况下不能被nested,当然特殊情况下也可以实现sections的嵌套。
* section如下所示:
* [section]
*
* 什么是comments?
* 在INI文件中注释语句是以分号“;”开始的。所有的所有的注释语句不管多长都是独占一行直到结束的。
* 在分号和行结束符之间的所有内容都是被忽略的。
* 注释实例如下:
* ;comments text
*/
namespace Steven
{
public class IniHelper
{
#region Fields
private string m_FullName = null;
private int m_ReadBufferSize = 512;
#endregion
#region Properties
public string FullName
{
get { return this.m_FullName; }
}
public int ReadBufferSize
{
get
{
return this.m_ReadBufferSize;
}
set
{
this.m_ReadBufferSize = value;
}
}
#endregion
#region Constructors
public IniHelper(string fullName = ".\\config.ini")
{
this.m_FullName = fullName;
}
#endregion
#region Fuction Declare
/// <summary>
/// 写入INI文件
/// </summary>
/// <param name="section">节点名称,这个字串不区分大小写[如[TypeName]]</param>
/// <param name="key">键,不区分大小写</param>
/// <param name="val">值</param>
/// <param name="filepath">INI文件的完整路径和文件名</param>
/// <returns>非零表示成功,零表示失败</returns>
[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filepath);
/// <summary>
/// 读取INI文件
/// </summary>
/// <param name="section">节点名称</param>
/// <param name="key">键</param>
/// <param name="defValue">读取异常的情况下的缺省值</param>
/// <param name="retval">stringbulider对象</param>
/// <param name="size">字节大小</param>
/// <param name="filePath">INI文件的完整路径和文件名</param>
/// <returns>复制到缓冲区的字节数量,其中不包括那些NULL中止字符。
/// 若缓冲区size不够大,不能容下全部信息,就返回nSize-1
/// 若section或key为NULL,则返回nSize-2</returns>
[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string defValue,
System.Text.StringBuilder retval, int size, string filePath);
#endregion
#region Public Functions
/// <summary>
/// 将指定类型写入文件
/// </summary>
/// <param name="Section">节点名称</param>
/// <param name="KeyName">参数名称</param>
/// <param name="KeyValue">参数值</param>
public void WriteIni<T>(string Section, string KeyName, T KeyValue)
{
long size = WritePrivateProfileString(Section, KeyName, KeyValue.ToString(), this.m_FullName);
if (size == 0)
{
throw new System.Exception("Writting data to ini file is fail" + System.Environment.NewLine + this.m_FullName);
}
}
/// <summary>
/// 从文件中读出指定类型
/// </summary>
/// <param name="Section">节点名称</param>
/// <param name="KeyName">参数名称</param>
/// <param name="DefaultValue">默认值</param>
/// <returns>读取值</returns>
public T ReadIni<T>(string Section, string KeyName, T DefaultValue)
{
var stringBulder = new System.Text.StringBuilder(this.m_ReadBufferSize);
long size = GetPrivateProfileString(Section, KeyName, DefaultValue.ToString(), stringBulder, this.m_ReadBufferSize, this.m_FullName);
if (size == this.m_ReadBufferSize - 1)
{
throw new System.Exception("The read buffer is small, please change the buffer size");
}
else if (size == this.m_ReadBufferSize - 2)
{
throw new System.Exception("The section or key is not found, please check it");
}
System.Type tp = typeof(T);
// 泛型Nullable判断,取其中的类型
if (tp.IsGenericType)
{
tp = tp.GetGenericArguments()[0];
}
//string直接返回转换
if (tp.Name.ToLower() == "string")
{
return (T)(object)stringBulder.ToString();
}
//反射获取TryParse方法
var TryParse = tp.GetMethod("TryParse",
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static,
System.Type.DefaultBinder,
new System.Type[] { typeof(string), tp.MakeByRefType() },
new System.Reflection.ParameterModifier[] { new System.Reflection.ParameterModifier(2) });
var parameters = new object[] { stringBulder.ToString(), System.Activator.CreateInstance(tp) };
bool success = (bool)TryParse.Invoke(null, parameters);
//成功返回转换后的值,否则返回类型的默认值
if (success)
{
return (T)parameters[1];
}
else
{
return default(T);
}
}
#region Delete
public void DeleteKey(string section, string key)
{
try
{
this.WriteIni<string>(section, key, null);
}
catch
{
throw;
}
}
public void DeleteSection(string section)
{
try
{
this.WriteIni<string>(section, null, null);
}
catch
{
throw;
}
}
public void DeleteAllSection()
{
try
{
this.WriteIni<string>(null, null, null);
}
catch
{
throw;
}
}
#endregion
#endregion
}
}
【CSharp】IniHelperWithGeneric
最新推荐文章于 2023-08-14 17:13:41 发布