当前位置:
首页 > Python基础教程 >
-
C#教程之文件缓存
缓存存储在文件中,根据过期时间过期,也可以手动删除。IIS回收进程时缓存不丢失。
代码:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Runtime.Serialization.Formatters.Binary; using System.Threading; namespace Common.Utils { /// <summary> /// 缓存工具类 /// </summary> public static class CacheUtil { #region 变量 /// <summary> /// 缓存路径 /// </summary> private static string folderPath = Application.StartupPath + "\\cache"; /// <summary> /// 锁 /// </summary> private static object _lock = new object(); private static BinaryFormatter formatter = new BinaryFormatter(); #endregion #region 构造函数 static CacheUtil() { if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } } #endregion #region SetValue 保存键值对 /// <summary> /// 保存键值对 /// </summary> public static void SetValue(string key, object value, int expirationMinutes = 0) { CacheData data = new CacheData(key, value); data.updateTime = DateTime.Now; data.expirationMinutes = expirationMinutes; string keyMd5 = GetMD5(key); string path = folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) { fs.SetLength(0); formatter.Serialize(fs, data); fs.Close(); } } } #endregion #region GetValue 获取键值对 /// <summary> /// 获取键值对 /// </summary> public static object GetValue(string key) { string keyMd5 = GetMD5(key); string path = folderPath + "\\" + keyMd5 + ".txt"; if (File.Exists(path)) { using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { CacheData data = (CacheData)formatter.Deserialize(fs); fs.Close(); if (data.expirationMinutes > 0 && DateTime.Now.Subtract(data.updateTime).TotalMinutes > data.expirationMinutes) { File.Delete(path); return null; } return data.value; } } return null; } #endregion #region Delete 删除 /// <summary> /// 删除 /// </summary> public static void Delete(string key) { string keyMd5 = GetMD5(key); string path = folderPath + "\\" + keyMd5 + ".txt"; if (File.Exists(path)) { lock (_lock) { File.Delete(path); } } } #endregion #region DeleteAll 全部删除 /// <summary> /// 全部删除 /// </summary> public static void DeleteAll() { string[] files = Directory.GetFiles(folderPath); foreach (string file in files) { File.Delete(file); } } #endregion #region 计算MD5值 /// <summary> /// 计算MD5值 /// </summary> private static string GetMD5(string value) { string base64 = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(value)).Replace("/", "-"); if (base64.Length > 200) { MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); byte[] bArr = md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(value)); StringBuilder sb = new StringBuilder(); foreach (byte b in bArr) { sb.Append(b.ToString("x2")); } return sb.ToString(); } return base64; } #endregion } #region CacheData 缓存数据 /// <summary> /// 缓存数据 /// </summary> [Serializable] public class CacheData { /// <summary> /// 键 /// </summary> public string key { get; set; } /// <summary> /// 值 /// </summary> public object value { get; set; } /// <summary> /// 缓存更新时间 /// </summary> public DateTime updateTime { get; set; } /// <summary> /// 过期时间(分钟),0表示永不过期 /// </summary> public int expirationMinutes { get; set; } public CacheData(string key, object value) { this.key = key; this.value = value; } } #endregion }
带文件依赖版:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using System.Runtime.Serialization.Formatters.Binary; using System.Threading; using System.Web; namespace Common.Utils { /// <summary> /// 缓存工具类 /// 缓存数据存储在文件中 /// </summary> public static class CacheUtil { #region 变量 /// <summary> /// 锁 /// </summary> private static object _lock = new object(); private static BinaryFormatter formatter = new BinaryFormatter(); #endregion #region SetValue 保存键值对 /// <summary> /// 保存键值对 /// </summary> public static void SetValue(HttpServerUtilityBase server, string key, object value, string dependentFilePath, int expirationMinutes = 0) { CacheData data = new CacheData(key, value); data.updateTime = DateTime.Now; data.expirationMinutes = expirationMinutes; data.dependentFilePath = dependentFilePath; string folderPath = server.MapPath("~/bin/cache"); if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } string keyMd5 = GetMD5(key); string path = folderPath + "\\" + keyMd5 + ".txt"; lock (_lock) { using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) { fs.SetLength(0); formatter.Serialize(fs, data); fs.Close(); } } } #endregion #region GetValue 获取键值对 /// <summary> /// 获取键值对 /// </summary> public static object GetValue(HttpServerUtilityBase server, string key) { string keyMd5 = GetMD5(key); string folderPath = server.MapPath("~/bin/cache"); string path = folderPath + "\\" + keyMd5 + ".txt"; if (File.Exists(path)) { using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { CacheData data = (CacheData)formatter.Deserialize(fs); fs.Close(); FileInfo fileInfo = new FileInfo(data.dependentFilePath); if (fileInfo.LastWriteTime > data.updateTime) { File.Delete(path); return null; } if (data.expirationMinutes > 0 && DateTime.Now.Subtract(data.updateTime).TotalMinutes > data.expirationMinutes) { File.Delete(path); return null; } return data.value; } } return null; } #endregion #region Delete 删除 /// <summary> /// 删除 /// </summary> public static void Delete(HttpServerUtilityBase server, string key) { string keyMd5 = GetMD5(key); string folderPath = server.MapPath("~/bin/cache"); string path = folderPath + "\\" + keyMd5 + ".txt"; File.Delete(path); } #endregion #region DeleteAll 全部删除 /// <summary> /// 全部删除 /// </summary> public static void DeleteAll(HttpServerUtilityBase server) { string folderPath = server.MapPath("~/bin/cache"); string[] files = Directory.GetFiles(folderPath); foreach (string file in files) { File.Delete(file); } } #endregion #region 计算MD5值 /// <summary> /// 计算MD5值 /// </summary> private static string GetMD5(string value) { string base64 = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(value)).Replace("/", "-"); if (base64.Length > 200) { MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); byte[] bArr = md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(value)); StringBuilder sb = new StringBuilder(); foreach (byte b in bArr) { sb.Append(b.ToString("x2")); } return sb.ToString(); } return base64; } #endregion } #region CacheData 缓存数据 /// <summary> /// 缓存数据 /// </summary> [Serializable] public class CacheData { /// <summary> /// 键 /// </summary> public string key { get; set; } /// <summary> /// 值 /// </summary> public object value { get; set; } /// <summary> /// 缓存更新时间 /// </summary> public DateTime updateTime { get; set; } /// <summary> /// 过期时间(分钟),0表示永不过期 /// </summary> public int expirationMinutes { get; set; } /// <summary> /// 缓存依赖文件路径 /// </summary> public string dependentFilePath { get; set; } public CacheData(string key, object value) { this.key = key; this.value = value; } } #endregion }
带文件依赖版使用示例:
public class ProductController : Controller { #region details页面 public ActionResult details(string name) { ViewBag.menu = "product"; string headKey = "NetCMS.Web.Controllers.ProductController.details.head." + name; string bodyKey = "NetCMS.Web.Controllers.ProductController.details.body." + name; string dependentFilePath = Server.MapPath("~/Theme/pages/product/" + name + ".html"); List<string> fileList = Directory.GetFiles(Server.MapPath("~/") + "Theme\\pages\\product").ToList(); string file = fileList.Find(a => { string fileName = Path.GetFileNameWithoutExtension(a); if (name == fileName) { return true; } return false; }); string html = string.Empty; if (CacheUtil.GetValue(Server, headKey) == null || CacheUtil.GetValue(Server, bodyKey) == null) { using (StreamReader sr = new StreamReader(file)) { html = sr.ReadToEnd(); sr.Close(); } } string body = string.Empty; string pre = "\"" + Url.Content("~/"); body = (string)CacheUtil.GetValue(Server, bodyKey); if (body == null) { Regex reg = new Regex(@"<!--\s*头部结束\s*-->((?:[\s\S])*)<!--\s*公共底部\s*-->", RegexOptions.IgnoreCase); Match m = reg.Match(html); if (m.Success) { body = m.Groups[1].Value; } else { body = string.Empty; } body = body.Replace("\"js/", pre + "Theme/js/"); body = body.Replace("\"css/", pre + "Theme/css/"); body = body.Replace("\"images/", pre + "Theme/images/"); body = body.Replace("(images/", "(" + Url.Content("~/") + "Theme/images/"); body = body.Replace("('images/", "('" + Url.Content("~/") + "Theme/images/"); body = body.Replace("\"uploads/", pre + "Theme/uploads/"); body = body.Replace("('uploads/", "('" + Url.Content("~/") + "Theme/images/"); body = HtmlUtil.RemoveBlank(body); CacheUtil.SetValue(Server, bodyKey, body, dependentFilePath); } ViewBag.body = body; string head = string.Empty; head = (string)CacheUtil.GetValue(Server, headKey); if (head == null) { Regex regHead = new Regex(@"<head>((?:[\s\S])*)</head>", RegexOptions.IgnoreCase); Match mHead = regHead.Match(html); if (mHead.Success) { head = mHead.Groups[1].Value; } else { head = string.Empty; } head = head.Replace("\"js/", pre + "Theme/js/"); head = head.Replace("\"css/", pre + "Theme/css/"); head = head.Replace("\"images/", pre + "Theme/images/"); head = head.Replace("(images/", "(" + Url.Content("~/") + "Theme/images/"); head = head.Replace("('images/", "('" + Url.Content("~/") + "Theme/images/"); head = head.Replace("\"uploads/", pre + "Theme/uploads/"); head = head.Replace("('uploads/", "('" + Url.Content("~/") + "Theme/images/"); CacheUtil.SetValue(Server, headKey, head, dependentFilePath); } ViewBag.head = head; return View(); } #endregion }
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式