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 { /// /// 读取、修改配置文件的帮助类。 /// /// /// 每行包括键和值,中间的分隔符默认是英文冒号。 /// 如果某行以双斜杠 // 或井号 # 开头,就表示此行内容是注释 /// public class cfgHelper { // 此处不能使用日志,因为日志配置部分引用了此工具,属于循环引用 //private static readonly ILog logger = LogManager.GetLogger( typeof( cfgHelper ) ); /// /// 框架的根目录,默认是在 /framework/ 目录下。 /// 你也可以在 web.config 的 appSettings 中,添加 framework 项,来自定义框架的根目录 /// 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 + "/"; } /// /// 框架配置文件的根目录,在 /framework/config/ 目录下 /// public static String ConfigRoot { get { return strUtil.Join( FrameworkRoot, "" ); } } /// /// 获取 web.config 的 AppSettings 中某项的值 /// /// 项的名称 /// 返回一个字符串值 public static String GetAppSettings( String key ) { return ConfigurationManager.AppSettings[key]; } /// /// 读取配置文件,将结果放到字典Dictionary中返回 /// /// 请使用绝对路径 /// 返回一个字符串字典 public static Dictionary Read( String absPath ) { return Read( absPath, defaultSeparator ); } /// /// 读取配置文件,返回一个对象。配置文件的路径是 /framework/config/{typeFullName}.config /// /// 对象的类型 /// 返回 T 类型的对象 public static T Read() { return ReadByFile( typeof( T ).Name + ".config" ); } /// /// 读取配置文件,返回一个对象。 /// /// 对象的类型 /// 纯文件名称,不包括路径(默认是在 /framework/config/ 目录下) /// 返回 T 类型的对象 private static T ReadByFile( String fileName ) { return ReadByFile( fileName, defaultSeparator ); } /// /// 读取配置文件,返回一个对象。 /// /// 对象的类型 /// 纯文件名称,不包括路径(默认是在 /framework/config/ 目录下) /// 键和值之间的分隔符 /// 返回 T 类型的对象 private static T ReadByFile( String fileName, char separator ) { String path = PathHelper.Map( strUtil.Join( cfgHelper.ConfigRoot, fileName ) ); return Read( path, separator ); } /// /// 读取配置文件,返回一个对象。 /// /// /// 配置文件的路径(相对路径,相对于项目的根目录) /// 返回 T 类型的对象 public static T Read( String path ) { return Read( path, defaultSeparator ); } /// /// 读取配置文件,然后将结果通过反射,赋值给 T 类型的对象并返回。 /// (对象的属性只支持 int/string/bool/decimal/DateTime 五种类型) /// /// 对象的类型 /// 配置文件的路径(相对路径,相对于项目的根目录) /// 键和值之间的分隔符 /// 返回一个对象 public static T Read( String path, char separator ) { Dictionary 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; } /// /// 读取配置文件,返回一个 Dictionary,键值都是字符串 /// /// 配置文件的路径(相对路径,相对于项目的根目录) /// 键和值之间的分隔符 /// 返回一个 Dictionary public static Dictionary 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 ); } /// /// 将 Dictionary 对象持久化到磁盘 /// /// 一个 Dictionary /// 配置文件的路径(相对路径,相对于项目的根目录) public static void Write( Dictionary dic, String path ) { Write( dic, path, defaultSeparator ); } /// /// 将 Dictionary 对象持久化到磁盘 /// /// 一个 Dictionary /// 配置文件的路径(相对路径,相对于项目的根目录) /// 键和值之间的分隔符 public static void Write( Dictionary 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 ); } /// /// 将对象持久化到磁盘。保存的路径是 /framework/config/{typeFullName}.config /// /// 某特定对象 public static void Write( Object obj ) { WriteToFile( obj, obj.GetType().Name + ".config" ); } /// /// 将对象持久化到磁盘。 /// /// 某特定对象 /// 纯文件名称,不包括路径(默认是在 /framework/config/ 下) public static void WriteToFile( Object obj, String fileName ) { WriteToFile( obj, fileName, defaultSeparator ); } /// /// 将对象持久化到磁盘 /// /// 某特定对象 /// 纯文件名称,不包括路径(默认是在 /framework/config/ 下) /// 键和值之间的分隔符 public static void WriteToFile( Object obj, String fileName, char separator ) { Dictionary dic = new Dictionary(); 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 ); } /// /// 将 Dictionary 序列化为字符串 /// /// /// public static String GetDicString( Dictionary dic ) { cfgHelper cfg = new cfgHelper(); cfg.Dic = dic; return cfg.ToString(); } //-------------------------------------------------------------- private String _content; /// /// 配置文件的内容 /// public String Content { get { if (_dictionary != null && _content == null) toString(); return _content; } set { _content = value; } } private char _separator = defaultSeparator; private char getSeparator() { return _separator; } /// /// 设置键和值之间的分隔符 /// /// public void setSeparator( char separator ) { _separator = separator; } private Dictionary _dictionary; /// /// 以 Dictionary 的形式设置或获取配置 /// public Dictionary Dic { get { if (_dictionary == null && strUtil.HasText( Content )) toDic( getSeparator() ); return _dictionary; } set { _dictionary = value; } } private Dictionary toDic( char separator ) { Dictionary result = new Dictionary(); 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 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(); } /// /// 配置文件的内容 /// /// public override String ToString() { return this.Content; } private static readonly char defaultSeparator = ':'; } }