C#利用FileSystemWatcher实时监控文件的增加,修改,重命名和删除

好多时候,我们都需要知道某些目录下的文件什么时候被修改、删除过等,如果能用miniFilter驱动过滤来做的话当然是最好不过了,这是内核级别的,当然也比较复杂。如果只是简单的记录就没必要用驱动过滤级别的来做了,用FileSystemWatcher来做就要简单得多。

FileSystemWatcher组件可以监视文件系统,并在文件系统发生改变时作出反应。FileSystemWatcher 常用于文件系统变更的监控,当被监视的文件夹目录被创建、修改、重命名或删除时,会触发以下事件:

1.Created: 当新建文件或者文件夹

2.Changed:当文件或者文件夹已经完成修改

3.Renamed:当文件或者文件夹完成重命名

4.Deleted:当文件或者文件夹被删除

5.Error:当变更过程发生错误

下面我们一起来完成一个文件监控实例。

 

一、实例化FileSystemWatcher类,并注册监听事件

  //创建一个FileSystemWatcher,并设置其属性
          FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(); 
          //设置监控的路径
          fileSystemWatcher.Path = “监控路径”;
          //是否监控指定路径中的子目录
          fileSystemWatcher.IncludeSubdirectories = true;
          //启用
          fileSystemWatcher.EnableRaisingEvents = true;

          //注册监听事件,Created、Changed、Deleted三个事件传递的参数是一样的,我们就用同一个方法来处理就可以了
          fileSystemWatcher.Changed += new FileSystemEventHandler(FileSystemWatcher_EventHandler);
          fileSystemWatcher.Created += new FileSystemEventHandler(FileSystemWatcher_EventHandler);
          fileSystemWatcher.Deleted += new FileSystemEventHandler(FileSystemWatcher_EventHandler);
          fileSystemWatcher.Renamed += new RenamedEventHandler(FileSystemWatcher_Renamed);
          fileSystemWatcher.Error += new ErrorEventHandler(FileSystemWatcher_Error);

 

二、事件处理

FileSystemEventArgs 对象成员有:Name、OldName、ChangeType、FullPath、OldFullPath等,看名就明白是什么了,这里不做过多解释。

 //创建一个FileSystemWatcher,并设置其属性
          FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(); 
          //设置监控的路径
          fileSystemWatcher.Path = “监控路径”;
          //是否监控指定路径中的子目录
          fileSystemWatcher.IncludeSubdirectories = true;
          //启用
          fileSystemWatcher.EnableRaisingEvents = true;

          //Created、Changed、Deleted三个事件的处理方法
          private static void FileSystemWatcher_EventHandler(object sender, FileSystemEventArgs e)
          {
                      Invoke(new Action(new Action(() =>
                      {
                             Console.WriteLine(e.Name+e.FullPath);
                      })));
          }
          //重命名事件的处理方法
          private void FileSystemWatcher_Renamed(object sender, RenamedEventArgs e)
          {
                      Invoke(new Action(new Action(() =>
                      {
                             Console.WriteLine(e.OldName+e.Name+e.FullPath);
                      })));
          } 
         //错误事件的处理方法
          private void FileSystemWatcher_Error(object sender, ErrorEventArgs e)
          {
                      Invoke(new Action(new Action(() =>
                      {
                             Console.WriteLine(e.ToString()));
                      })));
          }

这里需要注意一个问题:因为FileSystemWatcher类本身就是一个多线程的控件,在实例化一个FileSystemWatcher时就自动创建了一个线程,在事件处理的方法中需要使用委托的方式封送到主线程中处理。

//声明传递文件Created、Changed、Deleted对象和委托,用于文件增加、删除、修改时更新UI界面
private delegate void setLogDelegate(FileSystemEventArgs e); 

 

三、展示监控记录

监控的记录可以保存到文件和数据库中,这里就增加一个listView来展示就好了

代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FileWatcher
{
  public partial class Form1 : Form
  {
      private delegate void renameDelegate(RenamedEventArgs e); //声明传递RenamedEventArgs对象和委托,用于文件Renamed时更新UI界面
      private delegate void setLogDelegate(FileSystemEventArgs e); //声明传递文件Created、Changed、Deleted对象和委托,用于文件增加、删除、修改时更新UI界面
      private FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();
      private ColumnHeader chTime = new ColumnHeader();
      private ColumnHeader chEvent = new ColumnHeader();
      private ColumnHeader chFile = new ColumnHeader();
      private ColumnHeader chPath = new ColumnHeader();
     public Form1()
      {
          InitializeComponent();
          chTime.TextAlign = HorizontalAlignment.Center;
          chTime.Width = 130;
          chTime.Text = "时间";
          this.listViewInfo.Columns.Add(chTime);
          chEvent.TextAlign = HorizontalAlignment.Center;
          chEvent.Width = 80;
          chEvent.Text = "事件";
          this.listViewInfo.Columns.Add(chEvent);
          chFile.Width = 270;
          chFile.Text = "文件";
          this.listViewInfo.Columns.Add(chFile);
          chPath.Width = this.listViewInfo.Width - chTime.Width - chEvent.Width - chFile.Width - 21;
          chPath.Text = "位置";
          this.listViewInfo.Columns.Add(chPath);
          ColumnHeader chEnd = new ColumnHeader();
          chEnd.Width = 17;
          chEnd.Text = "";
          this.listViewInfo.Columns.Add(chEnd);
          this.listViewInfo.View = View.Details;
          this.listViewInfo.GridLines = true;
          fileSystemWatcher.Changed += new FileSystemEventHandler(FileSystemWatcher_EventHandler);
          fileSystemWatcher.Created += new FileSystemEventHandler(FileSystemWatcher_EventHandler);
          fileSystemWatcher.Deleted += new FileSystemEventHandler(FileSystemWatcher_EventHandler);
          fileSystemWatcher.Renamed += new RenamedEventHandler(FileSystemWatcher_Renamed);
          fileSystemWatcher.Error += new ErrorEventHandler(FileSystemWatcher_Error);
          fileSystemWatcher.IncludeSubdirectories = true;
          fileSystemWatcher.EnableRaisingEvents = true;
      }


      #region 文件增加、删除、修改时被调用的处理方法
      private void FileSystemWatcher_EventHandler(object sender, FileSystemEventArgs e)
      {
          if (listViewInfo.InvokeRequired)   //判断是否跨线程
          {
              listViewInfo.Invoke(new setLogDelegate(SetLog), new object[] { e });//使用委托将方法封送到UI主线程处理
          }
      }
      private void SetLog(FileSystemEventArgs e)
      {
          string strLog = "";
          switch (e.ChangeType.ToString())
          {
              case "Created":
                  strLog = "文件创建";
                  break;
              case "Changed":
                  strLog = "文件修改";
                  break;
              case "Deleted":
                  strLog = "文件删除";
                  break;
              default:
                  strLog = e.ChangeType.ToString();
                  break;
          }
          ListViewItem lvi = new ListViewItem();
          lvi.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");  
          lvi.SubItems.Add(strLog);  
          lvi.SubItems.Add(e.Name);  
          lvi.SubItems.Add(e.FullPath.Replace(e.Name,""));  
          listViewInfo.Items.Add(lvi);
      }
      #endregion

      #region 重命名方法
      private void FileSystemWatcher_Renamed(object sender, RenamedEventArgs e)
      {
          if (listViewInfo.InvokeRequired)
          {
              listViewInfo.Invoke(new renameDelegate(SetRenamedLog), new object[]{e});
          }
      }
      private void SetRenamedLog(RenamedEventArgs e)
      {
          //listViewInfo.Items.Add(string.Format("重命名:{0} 被换名为:{1}, {2}", e.OldName, e.Name, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
          ListViewItem lvi = new ListViewItem();
          lvi.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
          lvi.SubItems.Add("文件重命名");
          lvi.SubItems.Add(e.OldName + "被换名为:" + e.Name);
          lvi.SubItems.Add(e.FullPath.Replace(e.Name, ""));
          listViewInfo.Items.Add(lvi);
      }
      #endregion

      #region  错误事件的方法
      private void FileSystemWatcher_Error(object sender, ErrorEventArgs e)
      {
          if (listViewInfo.InvokeRequired)   //判断是否跨线程
          {
              //使用委托处理
              Invoke(new Action(new Action(() =>
              {
                  listViewInfo.Items.Add(string.Format("文件出错:{0}, {1}", e.ToString(), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
              })));
          }
      }
      #endregion

  }
}

以上就是C#利用FileSystemWatcher实时监控文件的增加,修改,重命名和删除的详细内容,更多关于C# FileSystemWatcher监控文件的资料请关注编程宝库其它相关文章!

在C#中,当引用类型需要转换的时候,经常会用到关键字is、as以及显式强转。本篇来体验这三者的用法。先来梳理.NET引用类型转换的"约定俗成",或者叫"惯例":子类可以隐式转换为父类/基 ...