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

作者:xgh815 时间:2021-08-21 05:46:28 

好多时候,我们都需要知道某些目录下的文件什么时候被修改、删除过等,如果能用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来展示就好了

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

代码:

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

}
}

来源:https://blog.csdn.net/xgh815/article/details/126193809

标签:C#,FileSystemWatcher,监控,文件
0
投稿

猜你喜欢

  • java web监听器统计在线用户及人数

    2023-12-14 14:42:52
  • Java数据结构之单链表详解

    2023-11-04 17:02:20
  • jenkins+maven+svn自动部署和发布的详细图文教程

    2023-08-24 05:18:07
  • java String 转成Double二维数组的方法

    2023-04-28 12:11:02
  • Kotlin与Java相互调用的完整实例

    2023-06-17 03:23:23
  • Mybatis-Plus自动填充更新操作相关字段的实现

    2022-01-14 20:43:01
  • 浅析Java编程中枚举类型的定义与使用

    2021-07-04 23:46:16
  • java 线程方法join简单用法实例总结

    2022-10-26 19:27:38
  • maven中配置项目的jdk版本无效的排查方式

    2023-07-18 21:43:42
  • java web实现简单留言板功能

    2021-10-29 17:22:31
  • 关于MyBatis模糊查询的几种实现方式

    2023-05-09 04:23:12
  • java面试常见问题之Hibernate总结

    2023-11-27 10:37:05
  • SpringBoot定时任务动态扩展ScheduledTaskRegistrar详解

    2023-04-23 08:44:06
  • java二维数组实现推箱子小游戏

    2022-08-31 10:18:40
  • C#微信公众号开发之自定义菜单

    2023-01-23 02:07:08
  • 关于LinkedList集合对元素进行增查删操作

    2022-09-23 11:48:45
  • Springboot整合支付宝支付功能

    2023-07-02 17:38:09
  • 深入理解C#中的枚举

    2022-06-03 02:58:34
  • C# Winform消息通知系统托盘气泡提示框ToolTip控件

    2023-01-13 23:31:02
  • OpenCV图像旋转Rotate的详细介绍

    2023-07-01 08:22:27
  • asp之家 软件编程 m.aspxhome.com