结合 FileSystemWatcher更好的使用配置文件

       真忙啊,好不容易来一次。

       大家在开发过程中或多或少的会使用一些置配文件来存储一些应用程序的配置信息。虽然.net WinForm下有了App.Config,WebForm下有了Web.Config,但很多时候我们都会创建自己的配置文件,用来存储连接字符串或者存储其他信息。 

       好了,切入正题!如果你只使用.net提供的配置文件存储信息,下面内容唯一的作用就是浪费您的时间和伤害你的眼睛.  关于怎样使用配置文件不是本文的主要内容。我假设大家使用了自己的配置文件,因为配置文件中的内容变动不太频繁,为了提高效率,在程序运行期间,一般只会从配置文件中读取一次信息,然后将其存储在缓存或者一个单实体类中。如此当然是方便高效。如果程序是一个运行时间不长的工具软件,这一切都是美好的,不会出任何问题。 但如果程序是一个执行时间很长或者干脆就是一个后台程序,或者是某台服务器上的Web程序。那痛苦就开始了。由于配置信息只会获取一次,当你的配置信息发生变化时,程序中使用的配置信息还是之前的版本,你不得不手动重启程序来反应最新的变化。如果的程序在异地的一个服务器上,那就只有吐血的份了。 

      解决办法有N种, 下面,就是我采用的解决办法: 
      使用 FileSystemWatcher!!!

     在我的的" 自动更新程序"中已经使用了一个Config.xml 存储远端服务器的一个URL,每隔20秒钟,自动更新程序连接到配置文件中记录的URL上获取更新文件。如果每次扫描远程服务器时都读一次配置文件,将会没有必要地浪费性能。 我用一个Config类来获取配置信息。 Config类是一个单实例类,在程序运行期间,他只有一个实例,并且一直存在。在第一次使用他时,创建一个实例,并且将配置信息保存到对像里。以后,只从这个对像中获取信息而不去读取配置文件。下面是一个Config类的简化版: 

      
None.gif using System;
None.gif
using System.IO;
None.gif
using System.Xml;
None.gif
namespace Unicom.Utility
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif
/**//// <summary>
InBlock.gif
/// Config 的摘要说明。
ExpandedSubBlockEnd.gif
/// </summary>

InBlock.gif public class Config
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//配置文件所在的路径
InBlock.gif
private const string FILE_PATH=@"\Data\config.xml";
InBlock.gif
InBlock.gif
public static Config _Instance=null; //一个Config对像
InBlock.gif
public static Config Instance
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
get
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//第一次使用,如果没有实例,创建一个
InBlock.gif
if(_Instance==null)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif _Instance
=new Config();
ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
return _Instance;
ExpandedSubBlockEnd.gif }

ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
private string _URL=string.Empty; //存储URL信息.
InBlock.gif
public string URL
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
get
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
return _URL;
ExpandedSubBlockEnd.gif }

ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
private FileSystemWatcher fileWatcher=null;
InBlock.gif
InBlock.gif
//读取配置信息
InBlock.gif
private string GetInfoFromFile()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//开始读取配置文件,如果指ConfigFilePath指定的是一个相对路径,则取当前应用程序下的相应路径,
InBlock.gif
//如果是绝对路径,采用绝对路径
InBlock.gif
XmlTextReader myXml=new XmlTextReader(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory,FILE_PATH));
InBlock.gif
InBlock.gif
try
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
return myXml.ReadElementString("URL");
ExpandedSubBlockEnd.gif }

InBlock.gif
catch(Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
throw ex;
ExpandedSubBlockEnd.gif }

InBlock.gif
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif myXml.Close();
ExpandedSubBlockEnd.gif }

ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
private Config()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif _URL
=GetInfoFromFile(); //读取并保存xml文件中的配置信息
InBlock.gif

InBlock.gif
string FullPath=Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory,FILE_PATH);
InBlock.gif
InBlock.gif
//监视指定的配置文件
InBlock.gif
fileWatcher=new FileSystemWatcher(Path.GetDirectoryName(FullPath),Path.GetFileName(FullPath));
InBlock.gif fileWatcher.Changed
+=new FileSystemEventHandler(OnChange);
InBlock.gif fileWatcher.NotifyFilter
=NotifyFilters.LastWrite; //监视最后写入时间
InBlock.gif
fileWatcher.EnableRaisingEvents=true;//允许触发事件
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
//配置文件变化时,重新读取配置信息
InBlock.gif
private void OnChange()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif _URL
=GetInfoFromFile();
ExpandedSubBlockEnd.gif }

InBlock.gif
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

None.gif

           这个类同样会有我上面提到的问题,现在我们使用FileSystemWatcher 类来解决,在msdn中的描述如下: 
   使用 FileSystemWatcher 监视指定目录中的更改。可监视指定目录中的文件或子目录的更改。该组件可以监视本地计算机、网络驱动器或远程计算机上的文件。  当被监视的文件发生改动时,FileSystemWatcher会触发相应的事件,比如:修改,创建. 
      FileSystemWatcher的以下成员很关键:   Changed 事件 , NotifyFilter 属性 。 NotifyFilter是一个枚举型成员,用来监视文件的更改种类,成员如下:

成员名称说明
Attributes 文件或文件夹的属性。4
CreationTime 文件或文件夹的创建时间。64
DirectoryName 目录名。2
FileName 文件名。1
LastAccess 文件或文件夹上一次打开的日期。32
LastWrite 上一次向文件或文件夹写入内容的日期。16
Security 文件或文件夹的安全设置。256
Size 文件或文件夹的大小。8

    我们只需LastWrite 这一个就足够用了。

        要让 FileSystemWatcher 在文件变化时通知我们,并且执行指定的代码,我们需要将要执行的方法注册到FileSystemWatcher的 Change事件中,设置好其他属性。 我们先定义一个方法,当配置文件变化时,重新读取配置信息。

      现在们来修改一个Config类。首先,添加一个成员 FileSystemWatcher
         
None.gif private FileSystemWatcher fileWatcher = null ;

    然后,在构造函数中添加以下代码 
     
None.gif // 监视指定的配置文件
None.gif
string FullPath = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory,FILE_PATH);
None.gif fileWatcher
= new FileSystemWatcher(Path.GetDirectoryName(FullPath),Path.GetFileName(FullPath));
None.gif fileWatcher.Changed
+= new FileSystemEventHandler(OnChange);
None.gif fileWatcher.NotifyFilter
= NotifyFilters.LastWrite; // 监视最后写入时间
None.gif
fileWatcher.EnableRaisingEvents = true ; // 允许触发事件
    
  在类里面添加一个新的方法:OnChange,用来重新获取配置信息
  
None.gif // 配置文件变化时,重新读取配置信息
None.gif
private void OnChange()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif _URL
=GetInfoFromFile();
ExpandedBlockEnd.gif }

   好了,一切搞定,在Config.xml发生修改时,最新的配置信息会在第一时间加载到内存中。 痛苦解除了。
    
    下面是修改后的完整的Config类

     
None.gif using System;
None.gif
using System.IO;
None.gif
using System.Xml;
None.gif
namespace Unicom.Utility
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif
/**//// <summary>
InBlock.gif
/// Config 的摘要说明。
ExpandedSubBlockEnd.gif
/// </summary>
InBlock.gif public class Config
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//配置文件所在的路径
InBlock.gif
private const string FILE_PATH=@"\Data\config.xml";
InBlock.gif
InBlock.gif
public static Config _Instance=null; //一个Config对像
InBlock.gif
public static Config Instance
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
get
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//第一次使用,如果没有实例,创建一个
InBlock.gif
if(_Instance==null)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif _Instance
=new Config();
ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
return _Instance;
ExpandedSubBlockEnd.gif }

ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
private string _URL=string.Empty; //存储URL信息.
InBlock.gif
public string URL
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
get
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
return _URL;
ExpandedSubBlockEnd.gif }

ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
private FileSystemWatcher fileWatcher=null;
InBlock.gif
InBlock.gif
//读取配置信息
InBlock.gif
private string GetInfoFromFile()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//开始读取配置文件,如果指ConfigFilePath指定的是一个相对路径,则取当前应用程序下的相应路径,
InBlock.gif
//如果是绝对路径,采用绝对路径
InBlock.gif
XmlTextReader myXml=new XmlTextReader(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory,FILE_PATH));
InBlock.gif
InBlock.gif
try
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
return myXml.ReadElementString("URL");
ExpandedSubBlockEnd.gif }

InBlock.gif
catch(Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
throw ex;
ExpandedSubBlockEnd.gif }

InBlock.gif
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif myXml.Close();
ExpandedSubBlockEnd.gif }

ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
private Config()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif _URL
=GetInfoFromFile(); //读取并保存xml文件中的配置信息
InBlock.gif
InBlock.gif
//监视指定的配置文件
InBlock.gif
string FullPath=Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory,FILE_PATH);
InBlock.gif fileWatcher
=new FileSystemWatcher(Path.GetDirectoryName(FullPath),Path.GetFileName(FullPath));
InBlock.gif fileWatcher.Changed
+=new FileSystemEventHandler(OnChange);
InBlock.gif fileWatcher.NotifyFilter
=NotifyFilters.LastWrite; //监视最后写入时间
InBlock.gif
fileWatcher.EnableRaisingEvents=true;//允许触发事件
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
//配置文件变化时,重新读取配置信息
InBlock.gif
private void OnChange()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif _URL
=GetInfoFromFile();
ExpandedSubBlockEnd.gif }

InBlock.gif
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

None.gif

转载于:https://www.cnblogs.com/cwbboy/archive/2005/04/20/141328.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值