C#中的文件系统观察程序

时间:2011-07-13 13:32:52

标签: c# .net filesystems

目前,我有一个Windows服务,可以持续监控4个文件夹。我使用FileSystemWatchers来监视文件夹。

但每次添加新文件夹时,我都必须卸载该服务,添加一个新的filesystemwatcher,然后安装该服务。

我正在考虑将其设置为动态或数据库驱动,每次程序需要监视新文件夹时,我都不必卸载并重新安装服务。

我怎样才能做到这一点?

提前致谢。

4 个答案:

答案 0 :(得分:3)

您可以使用应用程序定期读取和缓存新文件夹的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>

答案 1 :(得分:1)

使用配置文件添加新位置。然后,您只需在配置文件中添加新位置时重启服务即可。

答案 2 :(得分:0)

我会像@Yuck建议的那样使用.xml文件,但是,我只会看.xml文件。在服务启动时加载.xml,然后监视.xml文件以进行更改;如果.xml文件LastWriteTime发生更改,请重新加载。

答案 3 :(得分:0)

这里有一个使用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>