一个简单的配置文件读取类
做了个Windows服务使用app.config来保存是否开启调试输出内容(写记录到数据库),结果发现除非重新启动Windows服务,不然app.config中的更改是不会被读取的。
于是就自己整了个,里面加入了文件监视,这样在你更改文件内容时,可以马上读到配置更改后的内容,调试Windows服务时挺方便的,更值得一提的是.net的文件监视可以监视不存在的文件,这样你就可以随意建立或删除被监视文件

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using System.Web; using System.Web.Caching; using System.Reflection; using System.IO; namespace F.Studio.Common.Cfg { public class SimpleCfgMgr { private static readonly SimpleCfgMgr _Instance = new SimpleCfgMgr(); /// <summary> /// 需要提供默认配置文件SConfig.txt /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <param name="def"></param> /// <returns></returns> public static T GetV<T>(string key, T def) { return _Instance.GetCfg<T>(key, def); } /// <summary> /// 提供配置文件名称,不包括路径 /// 配置文件跟可执行文件需要在同一目录下 /// 内容是 /// key=value 这样一行一个配置 /// </summary> /// <param name="configFilename"></param> public SimpleCfgMgr(string configFilename) { this.ConfigFileanme = configFilename; this.CacheKey = "SimpleCfgMgr_" + Guid.NewGuid().ToString("N"); } /// <summary> /// 使用Sconfig.txt配置文件 /// </summary> private SimpleCfgMgr() { } private string ConfigFileanme = "SConfig.txt"; private string _CacheKey = "F.Studio.Common.Cfg.SimpleCfgMgr"; public string CacheKey { get { return _CacheKey; } private set { _CacheKey = value; } } private string FileName { get { return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigFileanme); } } private List<CfgRawItem> RawList { get { var rawList = HttpRuntime.Cache[CacheKey] as List<CfgRawItem>; if (rawList == null) { rawList = ParseContent(); var monitorFilename = FileName; try { var fileCacheDep = new CacheDependency(monitorFilename); System.Web.HttpRuntime.Cache.Add(CacheKey, rawList, fileCacheDep, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.High, null); } catch (Exception) { }; //Console.WriteLine("读取文件!"); } return rawList; } } /// <summary> /// 读取器 /// </summary> /// <param name="key"></param> /// <param name="defV"></param> /// <returns></returns> public T GetCfg<T>(string key, T defV) { var list = RawList; if (list == null || list.Count == 0) return defV; foreach (var item in RawList) { if (string.Compare(key, item.Key, true) == 0) { return TryParser<T>(item.Value, defV); } } return defV; } /// <summary> /// 解析器 /// </summary> /// <returns></returns> private List<CfgRawItem> ParseContent() { var txt = LoadTextContent().Trim(); var lines = txt.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); List<CfgRawItem> list = new List<CfgRawItem>(); foreach (string line in lines) { if (string.IsNullOrWhiteSpace(line) || string.IsNullOrEmpty(line)) continue; var str = line.Trim(); //忽略注释 if (str.StartsWith("/") || str.StartsWith("-") || str.StartsWith("*") || str.StartsWith("#")) continue; var index = str.IndexOf("="); if (index > 0 && str.Length > index + 1) //等号前后至少有一个非空字符 { var key = str.Substring(0, index); var value = str.Substring(index + 1, str.Length - index - 1); list.Add(new CfgRawItem(key.Trim(), value.Trim())); } } return list; } /// <summary> /// 加载器 /// </summary> /// <returns></returns> private string LoadTextContent() { if (!File.Exists(FileName)) { return string.Empty; } try { var content = File.ReadAllText(FileName); return content; } catch (Exception) { return string.Empty; } } ~SimpleCfgMgr() { HttpRuntime.Cache.Remove(CacheKey); } #region HelpMethod protected static T TryParser<T>(object v, T dValue) { if (v == null) { return dValue; } else { T t = default(T); try { if (t == null)//可空类型 { Type type = typeof(T); TypeConverter conv = TypeDescriptor.GetConverter(type); t = (T)conv.ConvertFrom(v); } else { t = (T)Convert.ChangeType(v, typeof(T)); } } catch { t = dValue; } return t; } } #endregion } #region Model public class CfgRawItem { public CfgRawItem(string key, string value) { this.Key = key; this.Value = value; } public string Key { get; set; } public string Value { get; set; } } #endregion }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
2012-03-18 关于端口共用
2011-03-18 .Net中的Interception--一个简单的AOP框架学习