用FileSystemWatcher监听自定义配置文件
一、 问题描述
我经常会遇到这样的场景:系统中有些自定义的配置文件,为了提升性能,可能会对已解析的配置做缓存。这样造成的结果就是每次更改配置都不得不重启应用程序,配置才会生效。但有时又不希望应用重启,于是问题来了:怎样才能不重启应用就让配置生效?
幸运的是,微软提供了FileSystemWatcher类来完成这个功能。下面就先来说说FileSystemWatcher。
二、 关于FileSystemWatcher
FileSystemWatcher: 侦听文件系统更改通知,并在目录或目录中的文件发生更改时引发事件。
FileSystemWatcher有几个重要且常用的属性:
| 属性名称 | 描述 |
| Path | 获取或设置要监视的目录的路径 |
| Filter | 获取或设置筛选字符串,用于确定在目录中监视哪些文件 |
| NotifyFilter | 获取或设置要监视的更改类型 |
| EnableRaisingEvents | 获取或设置一个值,该值指示是否启用此组件 |
Path和Filter用于指定监视的内容,NotifyFilter用于指定监视哪些变更,EnableRaisingEvents则用于指定监听器是否已启动。
FileSystemWatcher还有几个重要的事件:
| 事件名称 | 描述 |
| Changed | 当更改指定 Path中的文件和目录时发生 |
| Created | 当在指定 Path中创建文件和目录时发生 |
| Deleted | 删除指定 Path中的文件或目录时发 |
| Renamed | 重命名指定 Path中的文件或目录时发 |
在这个问题中,Changed事件就可以完成任务。
三、 解决方案
在做维护工具时,我喜欢把sql放到配置文件:
如:
<?xml version="1.0" encoding="utf-8" ?>
<sqls>
<sql name="getData">
<![CDATA[
Select * from table
]]>
</sql>
</sqls>
我的sqlManager可能如下:
{
private static XmlDocument SqlDoc;
private static readonly string ConfigPath = AppDomain.CurrentDomain.BaseDirectory + "\\Sqls\\Sql.xml";
static SqlManager()
{
SqlDoc = new XmlDocument();
SqlDoc.Load(ConfigPath);
}
public static string GetSql(string name)
{
var nodes = SqlDoc.SelectNodes("/sqls/sql");
foreach (XmlNode node in nodes)
{
if (node.Attributes["name"].Value.Equals(name, StringComparison.InvariantCultureIgnoreCase))
{
return node.InnerText;
}
}
return string.Empty;
}
}
为了实现开篇的要求,我将SqlManager修改如下:
{
private static XmlDocument SqlDoc;
private static readonly string ConfigPath = AppDomain.CurrentDomain.BaseDirectory + "\\Sqls\\Sql.xml";
private static FileSystemWatcher watcher;
static SqlManager()
{
SqlDoc = new XmlDocument();
SqlDoc.Load(ConfigPath);
watcher = new FileSystemWatcher(AppDomain.CurrentDomain.BaseDirectory + "\\Sqls", "*.*");
watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size ;
watcher.Changed += (obj, e) =>
{
SqlDoc.Load(ConfigPath);
};
}
public static string GetSql(string name)
{
var nodes = SqlDoc.SelectNodes("/sqls/sql");
foreach (XmlNode node in nodes)
{
if (node.Attributes["name"].Value.Equals(name, StringComparison.InvariantCultureIgnoreCase))
{
return node.InnerText;
}
}
return string.Empty;
}
}
这样以后每次修改sql语句就不用再重启应用了。
四、小结
本篇大致介绍了用FileSystemWatcher监听自定义配置文件,在配置文件发生更改自动应用最新配置的问题。关于FileSystemWatcher更详细的介绍请参见MSDN。
