📄 filecacheprovider.cs
字号:
//===============================================================================
// CSDN HeyCache
//===============================================================================
// 修改记录:[按最后修改时间倒排序]
// modify: 2007.06.14 by tangwei
// create: 2007.06.11 by tangwei
//
// 代码来源:tangwei
//===============================================================================
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Collections;
using System.Threading;
using HeyCacher.Components;
using HeyCacher.Components.Scavenger;
using HeyCacher.Components.Expirations;
using System.Collections.Specialized;
namespace HeyCacher.Providers
{
/// <summary>
/// 基于文件的缓存实现
/// </summary>
public class FileCacheProvider : CacheProvider
{
#region 属性
//文件存储目录
public string RootPath
{
get { return m_RootPath; }
}
private string m_RootPath;
//几级hash目录
public int PathDepth
{
get { return m_PathDepth; }
}
private int m_PathDepth;
//文件前缀
public string FileNameMark
{
get { return m_FileNameMark; }
}
private string m_FileNameMark;
#endregion
#region 初始化
/// <summary>
/// 初始化
/// </summary>
/// <param name="name"></param>
/// <param name="config"></param>
public override void Initialize(string name, NameValueCollection config)
{
//
int ScavengInSeconds = 10; //资源回收间隔时间,单位为秒
#region 初始化配置
base.Initialize(name, config);
if (config != null)
{
if (config["RootPath"] != null)
{
this.m_RootPath = config["RootPath"];
config.Remove("RootPath");
if(!String.IsNullOrEmpty(this.m_RootPath))
{
char pathHead = this.m_RootPath[0];
if (pathHead == '~')
{
this.m_RootPath = System.Web.HttpContext.Current.Server.MapPath(this.m_RootPath);
}
}
}
if (config["PathDepth"] != null)
{
this.m_PathDepth = int.Parse(config["PathDepth"]);
config.Remove("PathDepth");
}
if (config["FileNameMark"] != null)
{
this.m_FileNameMark = config["FileNameMark"];
config.Remove("FileNameMark");
}
if (config["ScavengInSeconds"] != null)
{
ScavengInSeconds = int.Parse(config["ScavengInSeconds"]);
config.Remove("ScavengInSeconds");
}
}
#endregion
//建立各种回收任务与控制器对象,并启动
ExpirationTask expirationTask = new ExpirationTask(this);
BackgroundScheduler scheduler = new BackgroundScheduler(expirationTask);
scheduler.Start();
//启动回收定时器
ScavengerTimer timer = new ScavengerTimer();
//timer.StartPolling(new TimerCallback(scheduler.ExpirationTimeoutExpired), ScavengInSeconds); //系统线程池定时器
timer.StartPolling(new System.Timers.ElapsedEventHandler(scheduler.ExpirationTimeoutExpired), ScavengInSeconds); //普通定时器
}
#endregion
#region Count
public override int Count
{
get { return -1; }
}
#endregion
#region Contains
public override bool Contains(string Key, CacheTack cacheTack)
{
//
string filename = null;
//取得缓存文件的存储路径
if (cacheTack == null || String.IsNullOrEmpty(cacheTack.SavePath))
{
filename = BuildFileFullPath(GetMd5Key(Key));
}
else
{
filename = GetFullPath(cacheTack.SavePath);
}
return File.Exists(filename);
}
#endregion
#region Get
public override CacheItem GetCacheItem(string Key, CacheTack cacheTack)
{
string filename = null;
CacheItem ci = null;
//取得缓存文件的存储路径
if (cacheTack == null || String.IsNullOrEmpty(cacheTack.SavePath))
{
filename = BuildFileFullPath(GetMd5Key(Key));
}
else
{
filename = GetFullPath(cacheTack.SavePath);
}
#region 更新本地依赖
ExpirationItem expirationItemBeforeLock = null;
//独占锁
bool LockFlag;
do
{
lock (ExpirationItemTable.SyncRoot)
{
if (!ExpirationItemTable.ContainsKey(Key))
{
ci = innerGet(filename);
if (ci != null)
{
expirationItemBeforeLock = new ExpirationItem(Key, ci.Priority, ci.RefreshAction, ci.Expirations);
ExpirationItemTable.Add(Key, expirationItemBeforeLock);
}
else
{
break;
}
}
else
{
expirationItemBeforeLock = (ExpirationItem)ExpirationItemTable[Key];
}
LockFlag = Monitor.TryEnter(expirationItemBeforeLock);
}
if (!LockFlag)
{
Thread.Sleep(0);
}
} while (!LockFlag);
//操作
if (expirationItemBeforeLock != null)
{
//过期
if (expirationItemBeforeLock.HasExpired())
{
expirationItemBeforeLock.TouchedByUserAction(true);
ExpirationItemTable.Remove(Key);
realRemove(Key, cacheTack);
return null;
}
}
//释放锁
if (expirationItemBeforeLock != null)
{
Monitor.Exit(expirationItemBeforeLock);
}
#endregion
//取得缓存
if (ci == null)
{
ci = innerGet(filename);
}
if (ci == null)
{
return null;
}
//返回缓存中的值
return ci;
}
private CacheItem innerGet(string filename)
{
CacheItem ci = null;
if (File.Exists(filename))
{
byte[] FileBytes = ReadFile(filename);
if (FileBytes != null)
{
ci = Cnlamar.Serialization.Deserialize(FileBytes, XmlSerialize, DataCompress) as CacheItem;
}
}
return ci;
}
#endregion
#region innerInsert
/// <summary>
/// 添加一个缓存项
/// </summary>
/// <param name="Replace"></param>
/// <param name="ci"></param>
/// <param name="Insertd"></param>
/// <returns></returns>
protected override object innerInsert(bool Replace, CacheItem ci, CacheTack cacheTack, out bool Insertd)
{
Insertd = false; //是否被插入
string filename = null;
//检查缓存项是否有了,有了的话,根据Replace进行删除或者返回
if (Contains(ci.Key))
{
if (Replace)
{
Remove(ci.Key);
}
else
{
return GetCacheItem(ci.Key, null).realValue;
}
}
//建立过期策略
ICacheItemExpiration[] LocalExpirations;
InsertCacheItemExpiration(ci, out LocalExpirations);
//取得缓存文件的存储路径
if (cacheTack == null || String.IsNullOrEmpty(cacheTack.SavePath))
{
filename = BuildFileFullPath(GetMd5Key(ci.Key));
}
else
{
filename = GetFullPath(cacheTack.SavePath);
}
//建立缓存项
byte[] byteCacheData = Cnlamar.Serialization.Serialize(ci, XmlSerialize, DataCompress);
//写文件
Insertd = WriteFile(filename, byteCacheData);
//判断返回
if (Insertd)
{
return ci.realValue;
}
else
{
return null;
}
}
private void InsertCacheItemExpiration(CacheItem ci, out ICacheItemExpiration[] LocalExpirations)
{
LocalExpirations = null; //本地过期策略
//如果过期规则为空,则不建立本地本地过期策略
if (ci.Expirations == null)
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -