缓存处理类(MemoryCache结合文件缓存)

Posted 漫漫洒洒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓存处理类(MemoryCache结合文件缓存)相关的知识,希望对你有一定的参考价值。

想提升站点的性能,于是增加了缓存,但是站点不会太大,于是不会到分布式memcached的缓存和redis这个nosql库,于是自己封装了.NET内置的缓存组件

原先使用System.Web.Caching.Cache,但是asp.net会在System.Web.Caching.Cache缓存页面等数据,于是替换了System.Web.Caching.Cache为MemoryCache。

而在使用MemoryCache的时候,重新启动网站会丢失缓存,于是加了自己的扩展,将缓存序列化存放在文件内,在缓存丢的时候从文件内获取缓存,做了简易的扩展。(现在应用在我的Cactus里面)

using System;
using System.Collections;
using System.Web;
using System.Text;
using System.IO;
using System.Runtime.Caching;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using System.Configuration;
using System.Collections.Generic;

namespace Cactus.Common
{
    /// <summary>
    /// 缓存对象数据结构
    /// </summary>
    [Serializable()]
    public class CacheData{
        public object Value { get;set;}
        public DateTime CreateTime { get; set; }
        public DateTimeOffset AbsoluteExpiration { get; set; }
        public DateTime FailureTime { get 
        { if (AbsoluteExpiration == System.Runtime.Caching.ObjectCache.InfiniteAbsoluteExpiration) 
            {
                return AbsoluteExpiration.DateTime;
            } 
            else { return CreateTime.AddTicks(AbsoluteExpiration.Ticks); } } 
        }
        public CacheItemPriority Priority { get; set; }
    }
    
    /// <summary>
    /// 缓存处理类(MemoryCache)
    /// </summary>
    public class CacheHelper
    {
        //在应用程序的同级目录(主要防止外部访问)
        public static string filePath = Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.ConnectionStrings["filecache"].ConnectionString);
        //文件扩展名
        public static string fileExt = ".cache";
        /// <summary>
        /// 获取数据缓存
        /// </summary>
        /// <param name="cacheKey"></param>
        public static object GetCache(string cacheKey)
        {
            //System.Web.Caching.Cache objCache = HttpRuntime.Cache;
            //return objCache[cacheKey];
            long i=System.Runtime.Caching.MemoryCache.Default.GetCount();
            CacheItem objCache=System.Runtime.Caching.MemoryCache.Default.GetCacheItem(cacheKey);
            if (objCache == null)
            {
                string _filepath = filePath + cacheKey + fileExt;
                if (File.Exists(_filepath))
                {
                    FileStream _file = File.OpenRead(_filepath);
                    if (_file.CanRead)
                    {
                        Debug.WriteLine("缓存反序列化获取数据:" + cacheKey);
                        object obj = CacheHelper.BinaryDeSerialize(_file);
                        CacheData _data = (CacheData)obj;
                        if (_data != null)
                        {
                            //判断是否过期
                            if (_data.FailureTime >= DateTime.Now)
                            {
                                //将数据添加到内存
                                CacheHelper.SetCacheToMemory(cacheKey, _data);
                                return _data.Value;
                            }
                            else
                            {
                                Debug.WriteLine("数据过期:" + cacheKey);
                                File.Delete(_filepath);
                                //数据过期
                                return null;
                            }
                        }
                        else { return null; }
                    }
                    else { return null; }
                }
                else { return null; }
            }
            else {
                CacheData _data = (CacheData)objCache.Value;
                return _data.Value;
            }
        }
        /// <summary>
        /// 内存缓存数
        /// </summary>
        /// <returns></returns>
        public static object GetCacheCount()
        {
            return System.Runtime.Caching.MemoryCache.Default.GetCount();
        }
        /// <summary>
        /// 文件缓存数
        /// </summary>
        /// <returns></returns>
        public static object GetFileCacheCount()
        {
            DirectoryInfo di = new DirectoryInfo(filePath);
            return di.GetFiles().Length;
        }
                
        /// <summary>
        /// 设置数据缓存
        /// </summary>
        public static bool SetCache(string cacheKey, object objObject, CacheItemPolicy policy)
        {
            //System.Web.Caching.Cache objCache = HttpRuntime.Cache;            
            //objCache.Insert(cacheKey, objObject);
            string _filepath = filePath + cacheKey + fileExt;
            if (Directory.Exists(filePath)==false) {
                Directory.CreateDirectory(filePath);
            }
            //设置缓存数据的相关参数
            CacheData data = new CacheData() { Value = objObject, CreateTime = DateTime.Now, AbsoluteExpiration = policy.AbsoluteExpiration, Priority = policy.Priority };
            CacheItem objCache = new CacheItem(cacheKey, data);
            FileStream stream = null;
            if (File.Exists(_filepath) == false)
            {
                stream = new FileStream(_filepath, FileMode.CreateNew, FileAccess.Write, FileShare.Write);
            }
            else {
                stream = new FileStream(_filepath, FileMode.Create, FileAccess.Write, FileShare.Write);
            }
            Debug.WriteLine("缓存序列化设置数据:" + cacheKey);
            CacheHelper.BinarySerialize(stream, data);
            return System.Runtime.Caching.MemoryCache.Default.Add(objCache, policy);
        }
        public static bool SetCacheToMemory(string cacheKey, CacheData data)
        {
            CacheItemPolicy policy = new CacheItemPolicy();
            CacheItem objCache = new CacheItem(cacheKey, data);
            policy.AbsoluteExpiration = data.AbsoluteExpiration;
            policy.Priority = CacheItemPriority.NotRemovable;
            return System.Runtime.Caching.MemoryCache.Default.Add(objCache, policy);
        }

        public static bool SetCache(string cacheKey, object objObject, DateTimeOffset AbsoluteExpiration)
        {
            //System.Web.Caching.Cache objCache = HttpRuntime.Cache;            
            //objCache.Insert(cacheKey, objObject);
            CacheItemPolicy _priority = new CacheItemPolicy();
            _priority.Priority = CacheItemPriority.NotRemovable;
            _priority.AbsoluteExpiration = AbsoluteExpiration;
            return SetCache(cacheKey, objObject, _priority);
        }

        public static bool SetCache(string cacheKey, object objObject, CacheItemPriority priority)
        {
            //System.Web.Caching.Cache objCache = HttpRuntime.Cache;            
            //objCache.Insert(cacheKey, objObject);
            CacheItemPolicy _priority = new CacheItemPolicy();
            _priority.Priority = priority;
            _priority.AbsoluteExpiration = System.Runtime.Caching.ObjectCache.InfiniteAbsoluteExpiration;
            return SetCache(cacheKey, objObject, _priority);
        }
        /// <summary>
        /// 设置数据缓存
        /// </summary>
        public static bool SetCache(string cacheKey, object objObject)
        {
            //System.Web.Caching.Cache objCache = HttpRuntime.Cache;
            //objCache.Insert(cacheKey, objObject, null, DateTime.MaxValue, timeout, System.Web.Caching.CacheItemPriority.NotRemovable, null);
            return CacheHelper.SetCache(cacheKey, objObject, System.Runtime.Caching.CacheItemPriority.NotRemovable);
        }

        /// <summary>
        /// 移除指定数据缓存
        /// </summary>
        public static void RemoveCache(string cacheKey)
        {
            //System.Web.Caching.Cache cache = HttpRuntime.Cache;
            //cache.Remove(cacheKey);
            System.Runtime.Caching.MemoryCache.Default.Remove(cacheKey);
            string _filepath = filePath + cacheKey + fileExt;
            File.Delete(_filepath);
        }

        /// <summary>
        /// 移除全部缓存
        /// </summary>
        public static void RemoveAllCache()
        {
            //System.Web.Caching.Cache cache = HttpRuntime.Cache;
            //IDictionaryEnumerator cacheEnum = cache.GetEnumerator();
            //while (cacheEnum.MoveNext())
            //{
            //    cache.Remove(cacheEnum.Key.ToString());
            //}
            MemoryCache _cache = System.Runtime.Caching.MemoryCache.Default;
            foreach (var _c in _cache.GetValues(null))
            {
                _cache.Remove(_c.Key);
            }
            DirectoryInfo di = new DirectoryInfo(filePath);
            di.Delete(true);
        }
        /// <summary>
        /// 清除指定缓存
        /// </summary>
        /// <param name="type">1:内存 2:文件</param>
        public static void RemoveAllCache(int type)
        {
            if (type == 1) 
            {
                MemoryCache _cache = System.Runtime.Caching.MemoryCache.Default;
                foreach (var _c in _cache.GetValues(null))
                {
                    _cache.Remove(_c.Key);
                }
            } 
            else if (type == 2)
            {
                DirectoryInfo di = new DirectoryInfo(filePath);
                di.Delete(true);
            } 
        }

        #region 流序列化
        public static void BinarySerialize(Stream stream, object obj)
        {
            try
            {
                stream.Seek(0, SeekOrigin.Begin);
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, obj);
            }
            catch (Exception e)
            {
                IOHelper.WriteDebug(e);
            }
            finally
            {
                //stream.Close();
                stream.Dispose();
            }
        }

        public static object BinaryDeSerialize(Stream stream)
        {
            object obj = null;
            stream.Seek(0, SeekOrigin.Begin);
            try
            {
                BinaryFormatter formatter = new BinaryFormatter();
                obj = formatter.Deserialize(stream);
            }
            catch (Exception e)
            {
                IOHelper.WriteDebug(e);
            }
            finally
            {
                //stream.Close();
                stream.Dispose();
            }
            return obj;
        }
        #endregion
    }
}

 

以上是关于缓存处理类(MemoryCache结合文件缓存)的主要内容,如果未能解决你的问题,请参考以下文章

MemoryCache 如何清除全部缓存?

分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S C/S项目均可以使用!

[爬虫学习笔记]MemoryCache缓存的用法学习

MemoryCache缓存 ---缓存时效

如何清除内存缓存?

.Net Core缓存组件(MemoryCache)缓存篇