首頁 > 軟體

C#利用FileSystemWatcher實時監控檔案的增加,修改,重新命名和刪除

2022-08-07 22:00:10

好多時候,我們都需要知道某些目錄下的檔案什麼時候被修改、刪除過等,如果能用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監控檔案的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com