使用C#如何監控選定文件夾中文件的變動情況?

来源:https://www.cnblogs.com/mingupupu/archive/2023/12/28/17933098.html
-Advertisement-
Play Games

目錄✨ 1、前言 2、效果 3、具體實現 ​ 頁面設計 ​ 全部代碼 ​ FileSystemWatcher的介紹 ​ FileSystemWatcher的構造函數 ​ FileSystemWatcher的屬性 ​ FileSystemWatcher的事件 4、總結 前言✨ 有時候我們會有監控電腦上 ...


目錄✨

1、前言

2、效果

3、具體實現

​ 頁面設計

​ 全部代碼

​ FileSystemWatcher的介紹

​ FileSystemWatcher的構造函數

​ FileSystemWatcher的屬性

​ FileSystemWatcher的事件

4、總結

前言✨

有時候我們會有監控電腦上某一個文件夾中文件變動情況的需求,在本文中,我也會以一個具體的例子,說明在C#中如何使用FileSystemWatcher類來實現上述需求。

效果✨

文件監控效果

image-20231227100851391

具體實現✨

如果你對C#如何監控選定文件夾中文件的變動情況感興趣,可以繼續往下閱讀。

界面設計

為了更好的演示效果,我這裡winform的界面設計如下:

image-20231227101050127

很簡單,只有一個button與一個richtextbox,button用來指定被監控的文件,richtextbox用來輸出一些信息。

全部代碼

namespace FileSystemWatcherDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            // 創建一個 FolderBrowserDialog 實例
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();

            // 設置對話框的標題
            folderBrowserDialog.Description = "選擇文件夾";

            // 如果用戶點擊了“確定”按鈕
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                richTextBox1.Text = "";
                // 獲取用戶選擇的文件夾路徑
                string selectedFolder = folderBrowserDialog.SelectedPath;

                // 提示被監控文件夾路徑
                richTextBox1.Text += $"被監控的文件夾為:{selectedFolder}\r\n";

                var watcher = new FileSystemWatcher($"{selectedFolder}");
               
                watcher.NotifyFilter = NotifyFilters.Attributes
                                | NotifyFilters.CreationTime
                                | NotifyFilters.DirectoryName
                                | NotifyFilters.FileName
                                | NotifyFilters.LastAccess
                                | NotifyFilters.LastWrite
                                | NotifyFilters.Security
                                | NotifyFilters.Size;

                watcher.Changed += OnChanged;
                watcher.Created += OnCreated;
                watcher.Deleted += OnDeleted;
                watcher.Renamed += OnRenamed;
                
                watcher.Filter = "*.txt";
                watcher.IncludeSubdirectories = true;
                watcher.EnableRaisingEvents = true;
            }
            else
            {
                MessageBox.Show("您本次沒有選擇文件夾!!!");
            }
          

           
   
        }

        private void AppendMessageToRichTextBox(string message)
        {
            // 在RichTextBox中添加提示信息        
            richTextBox1.Invoke(new Action(() =>
            {
                richTextBox1.AppendText(message + Environment.NewLine);
            }));
        }

        private void OnChanged(object sender, FileSystemEventArgs e)
        {
            if (e.ChangeType != WatcherChangeTypes.Changed)
            {
                return;
            }
            AppendMessageToRichTextBox($"Changed: {e.FullPath}");
        }

        private void OnCreated(object sender, FileSystemEventArgs e)
        {
            string value = $"Created: {e.FullPath}";
            AppendMessageToRichTextBox($"Created: {e.FullPath}");
        }

        private  void OnDeleted(object sender, FileSystemEventArgs e)
        {
            AppendMessageToRichTextBox($"Deleted: {e.FullPath}");
        }

        private  void OnRenamed(object sender, RenamedEventArgs e)
        {       
            AppendMessageToRichTextBox($"Renamed:");
            AppendMessageToRichTextBox($"    Old: {e.OldFullPath}");
            AppendMessageToRichTextBox($"    New: {e.FullPath} ");           
        }
     
    }
}

FileSystemWatcher的介紹

看過以上代碼,會發現核心就是FileSystemWatcher的使用。接下來我將介紹一下C#中的FileSystemWatcher類。

FileSystemWatcher是C#中的一個類,該類可以偵聽文件系統更改通知,併在目錄或目錄中的文件發生更改時引發事件。

FileSystemWatcher的構造函數

該類有三種構造函數,如下所示:

形式 含義
FileSystemWatcher() 初始化 FileSystemWatcher 類的新實例。
FileSystemWatcher(String) 初始化 FileSystemWatcher 類的新實例,給定要監視的目錄。
FileSystemWatcher(String, String) 初始化 FileSystemWatcher類的新實例,給定要監視的目錄和文件類型。
 var watcher = new FileSystemWatcher($"{selectedFolder}");

本文中我選擇的就是第二種構造函數,指定要監視的目錄。

FileSystemWatcher的屬性

現在介紹一下在本示例中用到的FileSystemWatcher的屬性,如下所示:

名稱 類型 含義
EnableRaisingEvents bool 設置FileSystemWatcher是否有效
Filter string 設置一個要監控的文件的格式
Filters Collection 設置多個要監控的文件的格式
IncludeSubdirectories bool 獲取或設置一個值,該值指示是否應監視指定路徑中的子目錄
NotifyFilter NotifyFilters 獲取或設置要監視的更改的類型
Path string 獲取或設置要監視的目錄的路徑

現在來解釋下所用到的代碼的含義:

watcher.Filter = "*.txt";

表示要監控的文件為.txt格式。

 watcher.IncludeSubdirectories = true;

表示指定路徑中的子目錄也要監視。

 watcher.EnableRaisingEvents = true;

表示該對象可以觸發事件,也就是還有效。

 watcher.NotifyFilter = NotifyFilters.Attributes
                                | NotifyFilters.CreationTime
                                | NotifyFilters.DirectoryName
                                | NotifyFilters.FileName
                                | NotifyFilters.LastAccess
                                | NotifyFilters.LastWrite
                                | NotifyFilters.Security
                                | NotifyFilters.Size;

設置要監視的更改的類型。NotifyFilter屬性的類型為NotifyFilters枚舉類型。

NotifyFilters枚舉類型:

[System.Flags]
public enum NotifyFilters

指定要在文件或文件夾中監視的更改。

此枚舉支持其成員值的按位組合。

該枚舉類型包含的值與含義如下所示:

名稱 含義
Attributes 文件或文件夾的屬性
CreationTime 文件或文件夾的創建時間
DirectoryName 目錄名
FileName 文件的名稱
LastAccess 文件或文件夾上一次打開的日期
LastWrite 上一次向文件或文件夾寫入內容的日期
Security 文件或文件夾的安全設置
Size 文件或文件夾的大小

在這裡使用了該枚舉類型的按位組合表示這幾種更改的類型要受到監視。

FileSystemWatcher的事件

FileSystemWatcher中的事件如下:

名稱 含義
Changed 當更改指定 Path 中的文件和目錄時發生
Created 當在指定Path 中創建文件和目錄時發生
Deleted 刪除指定Path中的文件或目錄時發生
Renamed 重命名指定 Path中的文件或目錄時發生
Error 當 FileSystemWatcher 的實例無法繼續監視更改或內部緩衝區溢出時發生
                watcher.Changed += OnChanged;
                watcher.Created += OnCreated;
                watcher.Deleted += OnDeleted;
                watcher.Renamed += OnRenamed;

在這裡我使用到了Changed、Created、Deleted和Renamed事件。

我將以Changed 事件為例,詳細解釋一下:

 watcher.Changed += OnChanged;

這行代碼的含義。

我們查看FileSystemWatcher的源代碼,Changed事件的代碼如下所示:

/// <devdoc>
///    Occurs when a file or directory in the specified <see cref='System.IO.FileSystemWatcher.Path'/> is changed.
/// </devdoc>
public event FileSystemEventHandler? Changed
{
    add
    {
        _onChangedHandler += value;
    }
    remove
    {
        _onChangedHandler -= value;
    }
}

可知將值賦給了_onChangedHandler,我們再來查看_onChangedHandler的定義:

 // Event handlers
 private FileSystemEventHandler? _onChangedHandler;

類型為FileSystemEventHandler?與Changed事件一致,再來看看FileSystemEventHandler?的定義:

 public delegate void FileSystemEventHandler(object sender, FileSystemEventArgs e);

發現是一個參數類型分別為object、FileSystemEventArgs返回值類型為空的委托類型。

object我們知道,那麼FileSystemEventArgs又是什麼呢?

查看它的源碼,截取一部分,如下所示:

public class FileSystemEventArgs : EventArgs
{
     private readonly WatcherChangeTypes _changeType;
     private readonly string? _name;
     private readonly string _fullPath;
     /// <devdoc>
///    Gets one of the <see cref='System.IO.WatcherChangeTypes'/> values.
/// </devdoc>
public WatcherChangeTypes ChangeType
{
    get
    {
        return _changeType;
    }
}

/// <devdoc>
///    Gets the fully qualified path of the affected file or directory.
/// </devdoc>
public string FullPath
{
    get
    {
        return _fullPath;
    }
}


/// <devdoc>
///       Gets the name of the affected file or directory.
/// </devdoc>
public string? Name
{
    get
    {
        return _name;
    }
}
 }

發現FileSystemEventArgs繼承自EventArgs,而EventArgs表示包含事件數據的類的基類,因此可以明白FileSystemEventArgs表示為目錄事件:Changed, Created, Deleted提供數據的類。

FileSystemEventArgs提供三個數據分別為ChangeType、FullPath、Name。

那ChangeType是什麼呢?

查看ChangeType的定義:

 //
 // 摘要:
 //     Changes that might occur to a file or directory.
 [Flags]
 public enum WatcherChangeTypes
 {
     //
     // 摘要:
     //     The creation of a file or folder.
     Created = 1,
     //
     // 摘要:
     //     The deletion of a file or folder.
     Deleted = 2,
     //
     // 摘要:
     //     The change of a file or folder. The types of changes include: changes to size,
     //     attributes, security settings, last write, and last access time.
     Changed = 4,
     //
     // 摘要:
     //     The renaming of a file or folder.
     Renamed = 8,
     //
     // 摘要:
     //     The creation, deletion, change, or renaming of a file or folder.
     All = 15
 }

是一個枚舉類型,表示更改的類型。

現在回過頭來看:

watcher.Changed += OnChanged;

OnChanged方法如下:

  private void OnChanged(object sender, FileSystemEventArgs e)
  {
      if (e.ChangeType != WatcherChangeTypes.Changed)
      {
          return;
      }
      AppendMessageToRichTextBox($"Changed: {e.FullPath}");
  }

為什麼可以將OnChanged方法訂閱到watcher.Changed事件上呢?

因為OnChanged方法與watcher.Changed事件中的委托類型FileSystemEventHandler的返回類型和簽名是相同的。

OnChanged方法的返回類型與簽名如下:

 private void OnChanged(object sender, FileSystemEventArgs e)

FileSystemEventHandler委托類型的定義如下:

 public delegate void FileSystemEventHandler(object sender, FileSystemEventArgs e);

現在已經理解了訂閱事件,那麼什麼時候觸發事件呢?

查看FileSystemWatcher的部分源碼:

 /// <devdoc>
 ///    Raises the <see cref='System.IO.FileSystemWatcher.Changed'/> event.
 /// </devdoc>
 protected void OnChanged(FileSystemEventArgs e)
 {
     InvokeOn(e, _onChangedHandler);
 }
 private void InvokeOn(FileSystemEventArgs e, FileSystemEventHandler? handler)
 {
     if (handler != null)
     {
         ISynchronizeInvoke? syncObj = SynchronizingObject;
         if (syncObj != null && syncObj.InvokeRequired)
             syncObj.BeginInvoke(handler, new object[] { this, e });
         else
             handler(this, e);
     }
 }

當發生相應的改變時,就會調用FileSystemWatcher類的OnChanged方法,從而觸發事件。

總結✨

本文通過一個實例,介紹瞭如何通過C#中的FileSystemWatcher類實現監控選定的文件夾,希望對你有所幫助。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 通過列表生成式,我們可以直接創建一個列表。但是,受到記憶體限制,列表容量肯定是有限的。而且,創建一個包含100萬個元素的列表,不僅占用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那後面絕大多數元素占用的空間都白白浪費了。 所以,如果列表元素可以按照某種演算法推算出來,那我們是否可以在迴圈的過程中不 ...
  • 上次給大家介紹了 支付寶 v3 自簽名如何實現 ,這次順便再把驗簽也寫一下。 為什麼要驗簽 說起為什麼要驗簽,如果要詳細一點解釋的話,可以寫很多很多...... 我們就簡單一點來解釋:驗簽可以證明接收到的信息是支付寶給我的,不是被人中途攔截篡改數據之後再發給我的。 支付寶的通知分為 「同步通知 」和 ...
  • 最近有同學問我,做後端開發項目時用php,java,c#,go,pathon...哪個好,從最近阿裡雲、美團伺服器崩潰來看,我想給你最直接的回答是,沒有完美的,只有適合自己的。 ...
  • 概述:C++記憶體分配有棧、堆和靜態存儲區三種方式。棧自動管理,適用於局部變數;堆手動管理,使用new和delete;靜態存儲區適用於全局變數,具有整個程式生命周期。通過清晰的示例源代碼,詳細解釋了它們的分配方法和使用步驟。 C++的記憶體分配涉及棧、堆和靜態存儲區,每種分配方式有其獨特的特點。以下是對 ...
  • 本文分享自華為雲社區《java進行資料庫操作的併發控制》,作者:張儉。 在現代應用編碼中,從資料庫裡面find出來,進行一些業務邏輯操作,最後再save回去。即: Person person = personRepo.findById(id); person.setAge(18); personRe ...
  • LASSO(Least Absolute Shrinkage and Selection Operator)回歸模型一般都是用英文縮寫表示,硬要翻譯的話,可翻譯為 最小絕對收縮和選擇運算元。 它是一種線性回歸模型的擴展,其主要目標是解決高維數據中的特征選擇和正則化問題。 1. 概述 在LASSO中,通 ...
  • 創建名為springboot_druid的新module,過程參考3.1節 5.1、引入相關依賴 註意:雖然本文使用的是 spring boot 2.7.18 和 MySQL 5.7 ,但是出於可移植性、可擴展性和相容性方面的考慮, druid 的啟動器使用的是 spring boot 3 版本的, ...
  • Cookie 1.HTTP無連接無狀態,Cookie和Session就是解決此問題。 2.客戶端向伺服器端發送一個請求的時,服務端向客戶端發送一個Cookie 然後瀏覽器將Cookie保存,之後每次HTTP請求瀏覽器都會將Cookie發送給伺服器端,需要衡量把什麼數據放到cookie中,很多數據並不 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...