zoukankan      html  css  js  c++  java
  • .net 序列化通用的方法

     1//是否写日志
      2#define txtLogAll
      3
      4using System;
      5using System.Web;
      6using System.Xml.Serialization;
      7using System.IO;
      8using System.Runtime.Serialization;
      9using System.Runtime.Serialization.Formatters.Soap;
     10using System.Runtime.Serialization.Formatters.Binary;
     11using System.Web.Caching;
     12using System.Threading;
     13using tjb.Utility.Caching;
     14using System.Xml;
     15using System.Text;
     16
     17
     18namespace tjb.Utility.Config
     19{
     20
     21    文件序列化的类型
     42
     43    /// <summary>
     44    /// 序列化基类  by Tjb 2007/06 
     45    /// T 类型不能创建多态的多个实例
     46    /// 优化和修正,增加配置文件备份 2008/9/18
     47    /// 修改:获取实例时加锁
     48    /// 修改:
     49    /// SaveAs(T Tobj, string FileFullName, bool BackupOnError) 方法增加线程锁定。防止多线程冲突 2008/10/24
     50    /// </summary>
     51    /// <typeparam name="T">T 必须有无参数的构造函数</typeparam>

     52    [Serializable]
     53    public abstract class IConfig<T> where T : IConfig<T>new()
     54    {
     55
     56        #region Exceptions
     57        private Exception __ConfigException;
     58        /// <summary>
     59        /// 读取或保存时发生的错误
     60        /// </summary>

     61        [XmlIgnore, SoapIgnore]
     62        public Exception Exception
     63        {
     64            get
     65            {
     66                return __ConfigException;
     67            }

     68            private set
     69            {
     70                if (value != null)
     71                {
     72                    HasError = true;
     73                    __ConfigException = value;
     74#if txtLogAll
     75                    Log.WriteLog(value);
     76#endif
     77                }

     78            }

     79        }

     80        private bool __HasError = false;
     81        /// <summary>
     82        /// 获取一个值 指示读取或者保存时是否发生错误
     83        /// 如果当前错误被获取后,此标志将被置为false
     84        /// </summary>

     85        [XmlIgnore, SoapIgnore]
     86        public bool HasError
     87        {
     88            get return __HasError; }
     89            private set { __HasError = value; }
     90        }

     91        #endregion

     92
     93        #region 序列化类型  可重写
     94
     95        private Formatter _CurrentFormatter = Formatter.Xml;
     96        /// <summary>
     97        /// 序列化的方式
     98        /// </summary>      

     99        [XmlIgnore]
    100        protected virtual Formatter CurrentFormatter
    101        {
    102            get
    103            {
    104                return _CurrentFormatter;
    105            }

    106            set
    107            {
    108                _CurrentFormatter = value;
    109            }

    110        }

    111
    112        #endregion

    113
    114        #region 获取单个实例
    115
    116        /// <summary>
    117        /// 获取Cache中缓存T的key
    118        /// </summary>

    119        public static string CacheKEY
    120        {
    121            get
    122            {
    123                // return typeof(T).GUID.ToString("N");
    124                return typeof(T).FullName;
    125            }

    126        }

    127        /// <summary>
    128        /// 从缓存(缓存KEY为T的命空间加类名)获取当前类的实例,如果缓存不存在则读取文件(ConfigFileFullName), 并缓存。 
    129        /// </summary>

    130        public static T Instance
    131        {
    132            get
    133            {
    134                T c = CacheUtility.Get<T>(CacheKEY);
    135                if (c == null)
    136                {
    137                    //这中方式无异于不加锁
    138                    //object Monitor = new object();
    139                    //lock (Monitor)
    140                    lock (typeof(T))
    141                    {
    142                        c = CacheUtility.Get<T>(CacheKEY);
    143                        if (c == null)
    144                        {
    145                            c = new T().Read();
    146#if DEBUG
    147                            CacheUtility.SetSlidingExpiration(CacheKEY, c, c.ConfigFileFullName, 7, CacheItemPriority.NotRemovable, new CacheItemRemovedCallback(CallR));
    148#else
    149                            CacheUtility.SetSlidingExpiration(CacheKEY, c, c.ConfigFileFullName, 7, CacheItemPriority.NotRemovable, null);
    150#endif
    151                        }

    152                    }

    153                }

    154                return c;
    155            }

    156        }

    157
    158        #endregion

    159
    160        #region Caching..
    161
    162        /// <summary>
    163        /// 从ConfigFileName指定文件以CurrentSerializeType读取实例,如果存在缓存则移除并重新进行缓存
    164        /// 如果不存在则以InitConfig初始化类,创建并保存文件
    165        /// </summary>
    166        /// <returns></returns>

    167        protected T ResetCacheAndRead()
    168        {
    169            ResetCache();
    170            return Read();
    171        }

    172        /// <summary>
    173        /// 移除CacheKEY 缓存
    174        /// </summary>

    175        public void ResetCache()
    176        {
    177            HttpRuntime.Cache.Remove(CacheKEY);
    178        }

    179        #endregion

    180
    181        #region 获取
    182
    183        /// <summary>
    184        /// 读取缓存中的实例如果不存在则
    185        /// 从ConfigFileName指定文件以CurrentSerializeType读取实例
    186        /// 如果不存在则以InitConfig初始化类,创建并保存文件
    187        /// </summary>
    188        /// <returns></returns>

    189        virtual protected T Read()
    190        {
    191            return Read(ConfigFileFullName, true, CurrentFormatter);
    192        }

    193
    194        /// <summary>
    195        ///  从ConfigFileName指定文件以CurrentSerializeType读取实例
    196        ///  如果不存在则以InitConfig初始化类,创建并保存文件
    197        /// </summary>
    198        /// <param name="configFileFullName">缓存文件绝对路径</param>
    199        /// <param name="serializeType"></param>
    200        /// <param name="BackupOnError">读取错误时是否备份</param>
    201        /// <returns></returns>

    202        protected T Read(string configFileFullName, bool BackupOnError, Formatter serializeType)
    203        {
    204            T t = CacheUtility.Get<T>(CacheKEY);
    205            if (t != null)
    206                return t;
    207            FileInfo fi = new FileInfo(configFileFullName);
    208            if (fi.Exists)
    209            {
    210
    211                FileStream fs = null;
    212                try
    213                {
    214                    open the stream
    236
    237                    if (fs != null)
    238                        fs.Close();
    239                }

    240                catch (Exception ex)
    241                {
    242                    if (fs != null)
    243                        fs.Close();
    244                    t = CustomizingInit();
    245
    246                    读取失败 进行备份 防止以后使用默认配置覆盖当前数据
    262
    263                    t.Exception = new Exception("读取配置文件时发生错误!将返回CustomizingInit()方法的实例,默认为 new T()!", ex);
    264                }

    265                finally
    266                {
    267
    268                }

    269            }

    270            else
    271            {
    272                t = CustomizingInit();
    273
    274                //不存在的同一文件不能读多次
    275                //防止在CustomizingInit()方法中调用Read(string configFileName, SerializeType serializeType) 造成死循环
    276                string ProtectedKEY = Thread.CurrentThread.ManagedThreadId + fi.FullName + "init";
    277                if (CacheUtility.GetAnyType<bool>(ProtectedKEY) == false)
    278                {
    279                    CacheUtility.SetAbsoluteExpiration(ProtectedKEY, truenull0.02);
    280                }

    281                else
    282                {
    283                    CacheUtility.Remove(ProtectedKEY);
    284                    throw new Exception("'" + fi.FullName + "' 文件不存在!读取过于频繁。导致此保护异常发生。");
    285                }

    286                t.Exception = new Exception("配置文件:'" + fi.FullName + "' 不存在!默认返回CustomizingInit()方法返回的实例。");
    287            }

    288            if (t == null)
    289                t.Exception = new Exception("发生错误,请检查初始化配置方法 CustomizingInit() 未返回的配置实例不能为空,或者系统中存在缓存 key :" + CacheKEY);
    290            return t;
    291        }

    292
    293#if DEBUG
    294        private static void CallR(string key, object obj, CacheItemRemovedReason re)
    295        {
    296#if txtLogAll
    297            Log.WriteLog(key + "::::" + re.ToString());
    298#endif
    299        }

    300#endif
    301
    302        #endregion

    303
    304        保存
    446
    447        删除配置文件
    476
    477        #region  抽象成员
    478        /// <summary>
    479        /// 返回派生类的当前实例
    480        /// protected override T Current
    481        /// {
    482        ///     get
    483        ///     {
    484        ///         return this;
    485        ///     }
    486        /// } 
    487        /// </summary>

    488        protected abstract T Current
    489        {
    490            get;
    491        }

    492        /// <summary>
    493        /// 自定义初始化配置类
    494        /// 获取 T 的配置实例时,如果配置文件不存在或者读取失败时返回此实例
    495        /// 重写中一般读取备份的配置文件,必须保证备份配置文件存在,否则发生异常。
    496        /// 默认返回    new T();
    497        /// </summary>
    498        /// <returns></returns>

    499        protected virtual T CustomizingInit()
    500        {
    501            return Current;
    502        }

    503        /// <summary>
    504        /// 配置文件名
    505        /// <c>配置文件名</c>
    506        /// <example>
    507        /// 配置文件名
    508        /// </example>
    509        /// </summary>

    510        private string ___file = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Config/" + typeof(T).Name + ".cfg");
    511        /// <summary>
    512        /// 配置文件全路径名
    513        /// 默认:winform 在应用程序目录;web应用程序默认bin目录。
    514        /// </summary>

    515        [XmlIgnore]
    516        public virtual string ConfigFileFullName
    517        {
    518            get
    519            {
    520                return ___file;
    521            }

    522            set
    523            {
    524                ___file = value;
    525            }

    526        }

    527        #endregion

    528    }

    529}

  • 相关阅读:
    Server Tomcat v8.0 Server at localhost was unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor.
    用户画像——“打标签”
    python replace函数替换无效问题
    python向mysql插入数据一直报TypeError: must be real number,not str
    《亿级用户下的新浪微博平台架构》读后感
    【2-10】标准 2 维表问题
    【2-8】集合划分问题(给定要分成几个集合)
    【2-7】集合划分问题
    【2-6】排列的字典序问题
    【2-5】有重复元素的排列问题
  • 原文地址:https://www.cnblogs.com/Traner/p/2819960.html
Copyright © 2011-2022 走看看