C#中的文件系统监视器
问题描述:
目前我有一个Windows服务,它不断监视4个文件夹。我已经使用FileSystemWatchers来监视文件夹。C#中的文件系统监视器
但是每次添加新文件夹时,我都要卸载服务添加一个新的filesystemwatcher然后安装服务。
我想让它动态或数据库驱动,我不需要卸载并重新安装服务,每次程序需要监视一个新的文件夹。
我该如何做到这一点?
在此先感谢。
答
在这里,你有一个使用XML与Linq2XML和拥有的配置文件更改支票演示:
class Program
{
static List<FileSystemWatcher> _watchers = new List<FileSystemWatcher>();
static bool _shouldReload = false;
static void WaitReady(string fileName)
{
while (true)
{
try
{
using (Stream stream = System.IO.File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
if (stream != null)
{
System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} ready.", fileName));
break;
}
}
}
catch (FileNotFoundException ex)
{
System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
}
catch (IOException ex)
{
System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
}
catch (UnauthorizedAccessException ex)
{
System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message));
}
Thread.Sleep(500);
}
}
static void Main(string[] args)
{
var configWatcher = new FileSystemWatcher(Path.GetDirectoryName(Path.GetFullPath("config.xml")), "config.xml");
configWatcher.Changed += (o, e) =>
{
lock (_watchers)
{
_watchers.ForEach(w => { w.EnableRaisingEvents = false; w.Dispose(); });
_watchers.Clear();
}
_shouldReload = true;
};
configWatcher.EnableRaisingEvents = true;
Thread t = new Thread((ThreadStart)(() => {
while (true)
{
Thread.Sleep(5000); // reload only every five seconds (safety measure)
if (_shouldReload)
{
_shouldReload = false;
Console.WriteLine("Reloading configuration.");
WaitReady(Path.GetFullPath("config.xml"));
loadConfigAndRun();
}
}
}));
t.IsBackground = true;
t.Start();
loadConfigAndRun();
Console.ReadLine();
}
static void loadConfigAndRun()
{
var config = XElement.Load("config.xml").Elements();
var paths = from watcher in config select watcher.Attribute("Folder").Value;
foreach (var path in paths)
{
var watcher = new FileSystemWatcher(path);
watcher.Created += new FileSystemEventHandler(watcher_Changed);
watcher.Changed += new FileSystemEventHandler(watcher_Changed);
watcher.Deleted += new FileSystemEventHandler(watcher_Changed);
watcher.Renamed += new RenamedEventHandler(watcher_Renamed);
watcher.EnableRaisingEvents = true;
_watchers.Add(watcher);
}
}
static void toggleWatcher(string path)
{
var watcher = _watchers.FirstOrDefault(w => w.Path == path);
if (watcher != null)
{
watcher.EnableRaisingEvents = !watcher.EnableRaisingEvents;
}
}
static void watcher_Renamed(object sender, RenamedEventArgs e)
{
var watcher = sender as FileSystemWatcher;
Console.WriteLine("Something renamed in " + watcher.Path);
}
static void watcher_Changed(object sender, FileSystemEventArgs e)
{
var watcher = sender as FileSystemWatcher;
Console.WriteLine("Something changed in " + watcher.Path);
}
}
这是config.xml文件:
<?xml version="1.0" encoding="utf-8" ?>
<Watchers>
<Watcher Folder="d:\ktm"></Watcher>
<Watcher Folder="c:\windows"></Watcher>
</Watchers>
答
您可以使用应用程序定期读取和缓存新文件夹的XML配置文件。这些将在app.settings
文件中进行。
<configuration>
<appSettings>
<add key = "FolderToWatch" value = "C:\SomeFolder\" />
<add key = "FolderToWatch" value = "C:\SomeFolder\AnotherOne\" />
<add key = "FolderToWatch" value = "D:\LastOne\" />
</appSettings>
</configuration>
答
使用配置文件添加您的新位置。然后,只需要在将新位置添加到配置文件时重新启动服务即可。
答
我会使用.YML建议的.xml文件,但是,我只会看.xml文件。服务启动时加载.xml文件,然后监视.xml文件以进行更改;如果LastWriteTime的.xml文件发生更改,请重新加载它。
通过21秒打我。 .. – AllenG