• C# FileSystemWatcher 实时监控文件的增加、修改、重命名和删除实例


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

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

    Created: 当新建文件或者文件夹
    Changed:当文件或者文件夹已经完成修改
    Renamed:当文件或者文件夹完成重命名
    Deleted:当文件或者文件夹被删除
    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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    二、事件处理

           FileSystemEventArgs 对象成员有:Name、OldName、ChangeType、FullPath、OldFullPath等,看名就明白是什么了,这里不做过多解释。
    
    • 1
     //创建一个FileSystemWatcher,并设置其属性
    FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(); 
    //设置监控的路径
    fileSystemWatcher.Path = “监控路径”;
    //是否监控指定路径中的子目录
    fileSystemWatcher.IncludeSubdirectories = true;
    //启用
    fileSystemWatcher.EnableRaisingEvents = true;
    
    //Created、Changed、Deleted三个事件的处理方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    private static void FileSystemWatcher_EventHandler(object sender, FileSystemEventArgs e)
    {
                Invoke(new Action(new Action(() =>
                {
                       Console.WriteLine(e.Name+e.FullPath);
                })));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    //重命名事件的处理方法
    
    • 1
    private void FileSystemWatcher_Renamed(object sender, RenamedEventArgs e)
    {
                Invoke(new Action(new Action(() =>
                {
                       Console.WriteLine(e.OldName+e.Name+e.FullPath);
                })));
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    //错误事件的处理方法

    private void FileSystemWatcher_Error(object sender, ErrorEventArgs e)
    {
                Invoke(new Action(new Action(() =>
                {
                       Console.WriteLine(e.ToString()));
                })));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这里需要注意一个问题:因为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
     
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
  • 相关阅读:
    C语言图钉画表白程序,给自己的偶像制作一个吧
    JavaEE——SpringBoot项目常见的依赖包及其作用
    SQL注入与PreparedStatement对象
    分享一些可以提升生信分析效率的vscode插件
    CPU vs GPU 的区别详解
    HashMap 随记
    智慧工地管理平台系统厂家哪家强|喜讯科技
    韩顺平-二维数组
    MybatisPlus
    Python---练习:求世界杯小组赛的总成绩(涉及:布尔类型转换为整型)
  • 原文地址:https://blog.csdn.net/weixin_45499836/article/details/126394074