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}

  • 相关阅读:
    WP7中HttpWebRequest的使用方法之GET方式
    C#使用技巧之调用JS脚本方法一
    SQL Server Date 函数之CONVERT()
    C#日期格式化和数字格式化
    C#使用技巧之调用JS脚本方法二
    Win8的RSS阅读器
    yield
    浮点类型(float、double)在内存中的存储
    从<<CSS禅意花园>>中学到的用户界面设计原则
    The First Essay
  • 原文地址:https://www.cnblogs.com/Traner/p/2819960.html
Copyright © 2011-2022 走看看