知识问答

C#的FileSystemWatcher用法实例详解

C# 的 FileSystemWatcher 类是一种监控文件变化的工具,允许我们监控一个特定的文件或者目录中的任一更改,比如内容修改、新增、删除等行为。下面,我将详细讲解 FileSystemWatcher 的使用方法,并附带两个示例说明。

前置条件

在使用 FileSystemWatcher 类之前,需要先引入 System.IO 命名空间,以便于访问所需的类和方法。

using System.IO;

监控目录的变化

在应用程序中,可以使用下面的代码来监控目录的变化,包括文件的创建、修改和删除等操作:

FileSystemWatcher watcher = new FileSystemWatcher();watcher.Path = "C:\\test";watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;watcher.Filter = "*.txt";watcher.Changed += new FileSystemEventHandler(OnChanged);watcher.Created += new FileSystemEventHandler(OnCreated);watcher.Deleted += new FileSystemEventHandler(OnDeleted);watcher.Renamed += new RenamedEventHandler(OnRenamed);watcher.EnableRaisingEvents = true;

上述代码创建了一个 FileSystemWatcher 的实例对象,并将监控的目录设置为 "C:\test"。使用 NotifyFilter 属性指定要监控的事件类型,这里包括文件的最后访问时间、最后修改时间、文件名以及目录名。Filter 属性用于指定要监视的文件类型,例如 "*.txt" 表示监控所有的文本文件类型。

另外,使用上述代码还定义了四个事件处理程序,分别对应于文件变化、创建、删除和重命名。例如,OnChanged 方法用于处理文件被修改的事件:

private static void OnChanged(object source, FileSystemEventArgs e){    Console.WriteLine($"File: {e.FullPath} {e.ChangeType}");}

在事件处理程序中,可以对文件的变化做出相应的处理操作。最后,将 EnableRaisingEvents 属性设置为 true,以启动 FileSystemWatcher 监控。

监控文件的变化

除了监控整个目录以外,还可以仅仅监控单个文件的变化,操作方法如下:

FileSystemWatcher watcher = new FileSystemWatcher();watcher.Path = "C:\\test\\test.txt";watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;watcher.Filter = "test.txt";watcher.Changed += new FileSystemEventHandler(OnChanged);watcher.EnableRaisingEvents = true;

上述代码中,创建了一个 FileSystemWatcher 的实例对象,并用 Path 属性指定要监控的文件路径。其余属性配置与之前的示例类似。需要注意,这种监控方式只能监控单个文件,不能监控整个目录内的文件变化。

示例说明

下面,我们将使用两个示例来进一步说明 FileSystemWatcher 的用法。

示例一:监控文件内容的变化

假设我们要监控一个文本文件,当其中的内容有变化时,将修改后的内容输出到命令行中。可以使用下面的代码实现:

static void Main(string[] args){    FileSystemWatcher watcher = new FileSystemWatcher();    watcher.Path = ".";    watcher.Filter = "test.txt";    watcher.NotifyFilter = NotifyFilters.LastWrite;    watcher.Changed += new FileSystemEventHandler(OnChanged);    Console.WriteLine("Starting to monitor changes...");    watcher.EnableRaisingEvents = true;    Console.ReadKey();}private static void OnChanged(object sender, FileSystemEventArgs e){    // wait for the file to be released    while (IsFileLocked(e.FullPath))    {        Thread.Sleep(500);    }    // read the file content    string content = string.Empty;    try    {        content = File.ReadAllText(e.FullPath);    }    catch (Exception ex)    {        Console.WriteLine(ex);    }    Console.WriteLine(content);}// check if the file is locked or notpublic static bool IsFileLocked(string filePath){    FileStream stream = null;    try    {        stream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);    }    catch (IOException)    {        return true;    }    finally    {        if (stream != null)        {            stream.Close();        }    }    return false;}

上述代码监视了当前目录下的 test.txt 文件,当其内容被修改时,将修改后的内容输出到命令行。在 OnChanged 方法中,使用 File.ReadAllText 方法读取文件内容,需要注意的是,在文件被编辑的过程中,该文件可能会被锁定,导致读取失败,因此可以使用一个 IsFileLocked 方法来检查文件是否被锁定,并在文件被释放之后再读取。

示例二:监控多个文件夹和文件

假设我们要监控多个文件夹和文件的变化,当其中任意一个文件或文件夹内的内容发生变化时,都可以及时地收到通知。可以使用如下代码实现:

static void Main(string[] args){    FileSystemWatcher dirWatcher = new FileSystemWatcher();    dirWatcher.Path = @"C:\test";    dirWatcher.IncludeSubdirectories = true;    dirWatcher.NotifyFilter = NotifyFilters.LastWrite;    dirWatcher.Changed += new FileSystemEventHandler(OnDirChanged);    dirWatcher.Created += new FileSystemEventHandler(OnDirChanged);    dirWatcher.EnableRaisingEvents = true;    FileSystemWatcher fileWatcher = new FileSystemWatcher();    fileWatcher.Path = @"C:\test\test.txt";    fileWatcher.NotifyFilter = NotifyFilters.LastWrite;    fileWatcher.Changed += new FileSystemEventHandler(OnFileChanged);    fileWatcher.EnableRaisingEvents = true;    Console.WriteLine("Starting to monitor changes...");    Console.ReadKey();}private static void OnDirChanged(object sender, FileSystemEventArgs e){    Console.WriteLine($"Directory: {e.FullPath} {e.ChangeType}");}private static void OnFileChanged(object sender, FileSystemEventArgs e){    Console.WriteLine($"File: {e.FullPath} {e.ChangeType}");}

上述代码监视了 C:\test 目录及其子目录下的所有文件和文件夹,以及 C:\test\test.txt 文件。当这些文件或文件夹的内容发生变化时,都将触发相应的事件处理程序,并输出对应的变化信息。

注:以上示例中的代码只是对 FileSystemWatcher 类的部分用法的说明,实际应用和使用场景会更为复杂,需要根据具体需求进行调整和完善。