349 lines
13 KiB
C#
349 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
using System.Text;
|
|
using System.IO;
|
|
using System.Configuration;
|
|
using System.Reflection;
|
|
using Zhaizj.Framework.Data.Config;
|
|
|
|
namespace Zhaizj.Framework {
|
|
|
|
/// <summary>
|
|
/// 读取、修改配置文件的帮助类。
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// 每行包括键和值,中间的分隔符默认是英文冒号。
|
|
/// 如果某行以双斜杠 // 或井号 # 开头,就表示此行内容是注释
|
|
/// </remarks>
|
|
public class cfgHelper {
|
|
|
|
// 此处不能使用日志,因为日志配置部分引用了此工具,属于循环引用
|
|
//private static readonly ILog logger = LogManager.GetLogger( typeof( cfgHelper ) );
|
|
|
|
/// <summary>
|
|
/// 框架的根目录,默认是在 /framework/ 目录下。
|
|
/// 你也可以在 web.config 的 appSettings 中,添加 framework 项,来自定义框架的根目录
|
|
/// </summary>
|
|
public static String FrameworkRoot = getFrameworkRoot();
|
|
|
|
private static String getFrameworkRoot() {
|
|
String root = string.Empty;// GetAppSettings("framework");
|
|
if (strUtil.IsNullOrEmpty(root)) return "/";
|
|
return root.EndsWith("/") ? root : root + "/";
|
|
}
|
|
|
|
/// <summary>
|
|
/// 框架配置文件的根目录,在 /framework/config/ 目录下
|
|
/// </summary>
|
|
public static String ConfigRoot {
|
|
get { return strUtil.Join( FrameworkRoot, "" ); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取 web.config 的 AppSettings 中某项的值
|
|
/// </summary>
|
|
/// <param name="key">项的名称</param>
|
|
/// <returns>返回一个字符串值</returns>
|
|
public static String GetAppSettings( String key ) {
|
|
return ConfigurationManager.AppSettings[key];
|
|
}
|
|
|
|
/// <summary>
|
|
/// 读取配置文件,将结果放到字典Dictionary中返回
|
|
/// </summary>
|
|
/// <param name="path">请使用绝对路径</param>
|
|
/// <returns>返回一个字符串字典</returns>
|
|
public static Dictionary<String, String> Read( String absPath ) {
|
|
return Read( absPath, defaultSeparator );
|
|
}
|
|
|
|
/// <summary>
|
|
/// 读取配置文件,返回一个对象。配置文件的路径是 /framework/config/{typeFullName}.config
|
|
/// </summary>
|
|
/// <typeparam name="T">对象的类型</typeparam>
|
|
/// <returns>返回 T 类型的对象</returns>
|
|
public static T Read<T>() {
|
|
return ReadByFile<T>( typeof( T ).Name + ".config" );
|
|
}
|
|
|
|
/// <summary>
|
|
/// 读取配置文件,返回一个对象。
|
|
/// </summary>
|
|
/// <typeparam name="T">对象的类型</typeparam>
|
|
/// <param name="fileName">纯文件名称,不包括路径(默认是在 /framework/config/ 目录下)</param>
|
|
/// <returns>返回 T 类型的对象</returns>
|
|
private static T ReadByFile<T>( String fileName ) {
|
|
return ReadByFile<T>( fileName, defaultSeparator );
|
|
}
|
|
|
|
/// <summary>
|
|
/// 读取配置文件,返回一个对象。
|
|
/// </summary>
|
|
/// <typeparam name="T">对象的类型</typeparam>
|
|
/// <param name="fileName">纯文件名称,不包括路径(默认是在 /framework/config/ 目录下)</param>
|
|
/// <param name="separator">键和值之间的分隔符</param>
|
|
/// <returns>返回 T 类型的对象</returns>
|
|
private static T ReadByFile<T>( String fileName, char separator ) {
|
|
String path = PathHelper.Map( strUtil.Join( cfgHelper.ConfigRoot, fileName ) );
|
|
return Read<T>( path, separator );
|
|
}
|
|
|
|
/// <summary>
|
|
/// 读取配置文件,返回一个对象。
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="path">配置文件的路径(相对路径,相对于项目的根目录)</param>
|
|
/// <returns>返回 T 类型的对象</returns>
|
|
public static T Read<T>( String path ) {
|
|
return Read<T>( path, defaultSeparator );
|
|
}
|
|
|
|
/// <summary>
|
|
/// 读取配置文件,然后将结果通过反射,赋值给 T 类型的对象并返回。
|
|
/// (对象的属性只支持 int/string/bool/decimal/DateTime 五种类型)
|
|
/// </summary>
|
|
/// <typeparam name="T">对象的类型</typeparam>
|
|
/// <param name="path">配置文件的路径(相对路径,相对于项目的根目录)</param>
|
|
/// <param name="separator">键和值之间的分隔符</param>
|
|
/// <returns>返回一个对象</returns>
|
|
public static T Read<T>( String path, char separator ) {
|
|
|
|
Dictionary<String, String> dic = Read( path, separator );
|
|
|
|
Object result = rft.GetInstance( typeof( T ) );
|
|
|
|
PropertyInfo[] arrp = typeof( T ).GetProperties();
|
|
foreach (PropertyInfo p in arrp) {
|
|
|
|
if (p.CanWrite == false) continue;
|
|
|
|
String valString;
|
|
dic.TryGetValue( p.Name, out valString );
|
|
if (valString == null) continue;
|
|
|
|
Object val = null;
|
|
if (p.PropertyType == typeof( int ))
|
|
val = cvt.ToInt( valString );
|
|
else if (p.PropertyType == typeof( Boolean ))
|
|
val = cvt.ToBool( valString );
|
|
else if (p.PropertyType == typeof( decimal ))
|
|
val = cvt.ToDecimal( valString );
|
|
else if (p.PropertyType == typeof( DateTime ))
|
|
val = cvt.ToTime( valString );
|
|
else if (p.PropertyType == typeof( String ))
|
|
val = valString;
|
|
|
|
p.SetValue( result, val, null );
|
|
|
|
}
|
|
|
|
return (T)result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 读取配置文件,返回一个 Dictionary,键值都是字符串
|
|
/// </summary>
|
|
/// <param name="path">配置文件的路径(相对路径,相对于项目的根目录)</param>
|
|
/// <param name="separator">键和值之间的分隔符</param>
|
|
/// <returns>返回一个 Dictionary</returns>
|
|
public static Dictionary<String, String> Read( String absPath, char separator ) {
|
|
cfgHelper cfg = new cfgHelper();
|
|
if (strUtil.IsNullOrEmpty(absPath))
|
|
{
|
|
cfg.Content = SectionLogHandler.Current.GetLogConfig();
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
cfg.Content = file.Read( absPath );
|
|
}
|
|
catch (IOException)
|
|
{
|
|
cfg.Content = "";
|
|
}
|
|
}
|
|
return cfg.toDic( separator );
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将 Dictionary 对象持久化到磁盘
|
|
/// </summary>
|
|
/// <param name="dic">一个 Dictionary</param>
|
|
/// <param name="path">配置文件的路径(相对路径,相对于项目的根目录)</param>
|
|
public static void Write( Dictionary<String, String> dic, String path ) {
|
|
Write( dic, path, defaultSeparator );
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将 Dictionary 对象持久化到磁盘
|
|
/// </summary>
|
|
/// <param name="dic">一个 Dictionary</param>
|
|
/// <param name="path">配置文件的路径(相对路径,相对于项目的根目录)</param>
|
|
/// <param name="separator">键和值之间的分隔符</param>
|
|
public static void Write( Dictionary<String, String> dic, String path, char separator ) {
|
|
if (strUtil.IsNullOrEmpty( path ))
|
|
throw new IOException( "config path is empty" );
|
|
|
|
cfgHelper cfg = new cfgHelper();
|
|
cfg.Dic = dic;
|
|
cfg.setSeparator( separator );
|
|
|
|
file.Write( PathHelper.Map( path ), cfg.Content );
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将对象持久化到磁盘。保存的路径是 /framework/config/{typeFullName}.config
|
|
/// </summary>
|
|
/// <param name="obj">某特定对象</param>
|
|
public static void Write( Object obj ) {
|
|
WriteToFile( obj, obj.GetType().Name + ".config" );
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将对象持久化到磁盘。
|
|
/// </summary>
|
|
/// <param name="obj">某特定对象</param>
|
|
/// <param name="fileName">纯文件名称,不包括路径(默认是在 /framework/config/ 下)</param>
|
|
public static void WriteToFile( Object obj, String fileName ) {
|
|
WriteToFile( obj, fileName, defaultSeparator );
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将对象持久化到磁盘
|
|
/// </summary>
|
|
/// <param name="obj">某特定对象</param>
|
|
/// <param name="fileName">纯文件名称,不包括路径(默认是在 /framework/config/ 下)</param>
|
|
/// <param name="separator">键和值之间的分隔符</param>
|
|
public static void WriteToFile( Object obj, String fileName, char separator ) {
|
|
|
|
Dictionary<String, String> dic = new Dictionary<String, String>();
|
|
PropertyInfo[] arrp = obj.GetType().GetProperties();
|
|
foreach (PropertyInfo p in arrp) {
|
|
if (p.CanRead == false) continue;
|
|
Object val = p.GetValue( obj, null );
|
|
dic[p.Name] = (val == null ? null : val.ToString());
|
|
}
|
|
|
|
String path = strUtil.Join( cfgHelper.ConfigRoot, fileName );
|
|
|
|
Write( dic, path, separator );
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将 Dictionary 序列化为字符串
|
|
/// </summary>
|
|
/// <param name="dic"></param>
|
|
/// <returns></returns>
|
|
public static String GetDicString( Dictionary<String, String> dic ) {
|
|
cfgHelper cfg = new cfgHelper();
|
|
cfg.Dic = dic;
|
|
return cfg.ToString();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
private String _content;
|
|
|
|
/// <summary>
|
|
/// 配置文件的内容
|
|
/// </summary>
|
|
public String Content {
|
|
get {
|
|
if (_dictionary != null && _content == null)
|
|
toString();
|
|
return _content;
|
|
}
|
|
set { _content = value; }
|
|
}
|
|
|
|
private char _separator = defaultSeparator;
|
|
|
|
private char getSeparator() {
|
|
return _separator;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置键和值之间的分隔符
|
|
/// </summary>
|
|
/// <param name="separator"></param>
|
|
public void setSeparator( char separator ) {
|
|
_separator = separator;
|
|
}
|
|
|
|
private Dictionary<String, String> _dictionary;
|
|
|
|
/// <summary>
|
|
/// 以 Dictionary 的形式设置或获取配置
|
|
/// </summary>
|
|
public Dictionary<String, String> Dic {
|
|
get {
|
|
if (_dictionary == null && strUtil.HasText( Content ))
|
|
toDic( getSeparator() );
|
|
return _dictionary;
|
|
}
|
|
set { _dictionary = value; }
|
|
}
|
|
|
|
private Dictionary<String, String> toDic( char separator ) {
|
|
|
|
Dictionary<String, String> result = new Dictionary<String, String>();
|
|
|
|
String[] arrLine = Content.Split( new char[] { '\n', '\r' } );
|
|
|
|
foreach (String oneLine in arrLine) {
|
|
|
|
//无值的行跳过
|
|
if (strUtil.IsNullOrEmpty( oneLine )) continue;
|
|
|
|
//注释行跳过
|
|
if (oneLine.StartsWith( "//" ) || oneLine.StartsWith( "#" )) continue;
|
|
|
|
String[] arrPair = oneLine.Split( new char[] { separator }, 2 );
|
|
if (arrPair.Length < 2) continue;
|
|
|
|
char[] arrTrim = new char[] { '"', '\'' };
|
|
|
|
String itemKey = arrPair[0].Trim().TrimStart( arrTrim ).TrimEnd( arrTrim ).Trim();
|
|
String itemValue = arrPair[1].Trim().TrimStart( arrTrim ).TrimEnd( arrTrim ).Trim();
|
|
|
|
result[itemKey] = itemValue;
|
|
|
|
}
|
|
|
|
_dictionary = result;
|
|
|
|
return result;
|
|
}
|
|
|
|
private void toString() {
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
char s = getSeparator();
|
|
foreach (KeyValuePair<String, String> pair in this.Dic) {
|
|
sb.Append( pair.Key );
|
|
sb.Append( " " );
|
|
sb.Append( s );
|
|
sb.Append( " " );
|
|
sb.Append( pair.Value );
|
|
sb.Append( Environment.NewLine );
|
|
}
|
|
|
|
_content = sb.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 配置文件的内容
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override String ToString() {
|
|
return this.Content;
|
|
}
|
|
|
|
private static readonly char defaultSeparator = ':';
|
|
|
|
}
|
|
}
|