程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#實現對文件目錄的實時監控

C#實現對文件目錄的實時監控

編輯:C#入門知識

 本文主要描述如何通過C#實現實時監控文件目錄下的變化,包括文件和目錄的添加,刪除,修改和重命名等操作。     首先,我們需要對.net提供的FileSystemWatcher類有所了解。我有些懶,找了MSDN對該類的描述。     FileSystemWatcher類偵聽文件系統更改通知,並在目錄或目錄中的文件發生更改時引發事件。     使用 FileSystemWatcher 監視指定目錄中的更改。可監視指定目錄中的文件或子目錄的更改。可以創建一個組件來監視本地計算機、網絡驅動器或遠程計算機上的文件。     若要監視所有文件中的更改,請將 Filter 屬性設置為空字符串 ("") 或使用通配符(“*.*”)。若要監視特定的文件,請將 Filter 屬性設置為該文件名。例如,若要監視文件 MyDoc.txt 中的更改,請將 Filter 屬性設置為“MyDoc.txt”。也可以監視特定類型文件中的更改。例如,若要監視文本文件中的更改,請將 Filter 屬性設置為“*.txt”。     可監視目錄或文件中的若干種更改。例如,可監視文件或目錄的 Attributes、LastWrite 日期和時間或 Size 方面的更改。通過將 NotifyFilter 屬性設置為 NotifyFilters 值之一來達到此目的。有關可監視的更改類型的更多信息,請參見 NotifyFilters。     可監視文件或目錄的重命名、刪除或創建。例如,若要監視文本文件的重命名,請將 Filter 屬性設置為“*.txt”,並使用為其參數指定的 Renamed 來調用 WaitForChanged 方法。     Windows 操作系統在 FileSystemWatcher 創建的緩沖區中通知組件文件發生更改。如果短時間內有很多更改,則緩沖區可能會溢出。這將導致組件失去對目錄更改的跟蹤,並且它將只提供一般性通知。使用 InternalBufferSize 屬性來增加緩沖區大小的開銷較大,因為它來自無法換出到磁盤的非頁面內存,所以應確保緩沖區大小適中(盡量小,但也要有足夠大小以便不會丟失任何文件更改事件)。若要避免緩沖區溢出,請使用 NotifyFilter 和 IncludeSubdirectories 屬性,以便可以篩選掉不想要的更改通知。     使用 FileSystemWatcher 類時,請注意以下事項。     1) 對包括隱藏文件(夾)在內的所有文件(夾)進行監控。     2) 您可以為 InternalBufferSize 屬性(用於監視網絡上的目錄)設置的最大大小為 64 KB。     FileSystemWatcher的實例監控到文件(夾)的變化後,會觸發相應的事件,其中文件(夾)的添加,刪除和修改會分別觸發Created,Deleted,Changed事件,文件(夾)重命名時觸發OnRenamed事件。          然後,在熟悉了FileSystemWatcher類後,我們開始自己的程序編寫。     實例化FileSystemWatcher類,並傳入需要監控的目錄路徑,以及是否制定監控的文件類型(文章前面有所介紹)。   _watcher = new FileSystemWatcher(_path, _filter);   注冊監聽事件,以及編寫事件觸發後相關的處理邏輯。   _watcher.Created += new FileSystemEventHandler(OnChanged);             _watcher.Changed += new FileSystemEventHandler(OnChanged);             _watcher.Deleted += new FileSystemEventHandler(OnChanged);             _watcher.Renamed += new RenamedEventHandler(OnRenamed);             _watcher.IncludeSubdirectories = true;             _watcher.EnableRaisingEvents = true;   在本程序中,專門定義了一個FileChangeInformation類來記錄文件變化信息,並定義了一個CustomQueue類,該類類似於Queue類,是一個數據先進先出的集合,用來存儲所有的文件變化消息,並提供數據持久化功能。     監控類 - FileWatcher,代碼如下:   復制代碼   1  /// <summary>   2     /// 文件監控類,用於監控指定目錄下文件以及文件夾的變化   3     /// </summary>   4     public class FileWatcher   5     {   6         private FileSystemWatcher _watcher = null;   7         private string _path = string.Empty;   8         private string _filter = string.Empty;   9         private bool _isWatch = false;  10         private CustomQueue<FileChangeInformation> _queue = null;  11   12         /// <summary>  13         /// 監控是否正在運行  14         /// </summary>  15         public bool IsWatch  16         {  17             get  18             {  19                 return _isWatch;  20             }  21         }  22   23         /// <summary>  24         /// 文件變更信息隊列  25         /// </summary>  26         public CustomQueue<FileChangeInformation> FileChangeQueue  27         {  28             get  29             {  30                 return _queue;  31             }  32         }  33   34         /// <summary>  35         /// 初始化FileWatcher類  36         /// </summary>  37         /// <param name="path">監控路徑</param>  38         public FileWatcher(string path)  39         {  40             _path = path;  41             _queue = new CustomQueue<FileChangeInformation>();  42         }  43         /// <summary>  44         /// 初始化FileWatcher類,並指定是否持久化文件變更消息  45         /// </summary>  46         /// <param name="path">監控路徑</param>  47         /// <param name="isPersistence">是否持久化變更消息</param>  48         /// <param name="persistenceFilePath">持久化保存路徑</param>  49         public FileWatcher(string path, bool isPersistence, string persistenceFilePath)  50         {  51             _path = path;  52             _queue = new CustomQueue<FileChangeInformation>(isPersistence, persistenceFilePath);  53         }  54   55         /// <summary>  56         /// 初始化FileWatcher類,並指定是否監控指定類型文件  57         /// </summary>  58         /// <param name="path">監控路徑</param>  59         /// <param name="filter">指定類型文件,格式如:*.txt,*.doc,*.rar</param>  60         public FileWatcher(string path, string filter)  61         {  62             _path = path;  63             _filter = filter;  64             _queue = new CustomQueue<FileChangeInformation>();  65         }  66   67         /// <summary>  68         /// 初始化FileWatcher類,並指定是否監控指定類型文件,是否持久化文件變更消息  69         /// </summary>  70         /// <param name="path">監控路徑</param>  71         /// <param name="filter">指定類型文件,格式如:*.txt,*.doc,*.rar</param>  72         /// <param name="isPersistence">是否持久化變更消息</param>  73         /// <param name="persistenceFilePath">持久化保存路徑</param>  74         public FileWatcher(string path, string filter, bool isPersistence, string persistenceFilePath)  75         {  76             _path = path;  77             _filter = filter;  78             _queue = new CustomQueue<FileChangeInformation>(isPersistence, persistenceFilePath);  79         }  80   81         /// <summary>  82         /// 打開文件監聽器  83         /// </summary>  84         public void Open()  85         {  86             if (!Directory.Exists(_path))  87             {  88                 Directory.CreateDirectory(_path);  89             }  90   91             if (string.IsNullOrEmpty(_filter))  92             {  93                 _watcher = new FileSystemWatcher(_path);  94             }  95             else  96             {  97                 _watcher = new FileSystemWatcher(_path, _filter);  98             }  99             //注冊監聽事件 100             _watcher.Created += new FileSystemEventHandler(OnProcess); 101             _watcher.Changed += new FileSystemEventHandler(OnProcess); 102             _watcher.Deleted += new FileSystemEventHandler(OnProcess); 103             _watcher.Renamed += new RenamedEventHandler(OnFileRenamed); 104             _watcher.IncludeSubdirectories = true; 105             _watcher.EnableRaisingEvents = true; 106             _isWatch = true; 107         } 108  109         /// <summary> 110         /// 關閉監聽器 111         /// </summary> 112         public void Close() 113         { 114             _isWatch = false; 115             _watcher.Created -= new FileSystemEventHandler(OnProcess); 116             _watcher.Changed -= new FileSystemEventHandler(OnProcess); 117             _watcher.Deleted -= new FileSystemEventHandler(OnProcess); 118             _watcher.Renamed -= new RenamedEventHandler(OnFileRenamed); 119             _watcher.EnableRaisingEvents = false; 120             _watcher = null; 121         } 122  123         /// <summary> 124         /// 獲取一條文件變更消息 125         /// </summary> 126         /// <returns></returns> 127         public FileChangeInformation Get() 128         { 129             FileChangeInformation info = null; 130             if (_queue.Count > 0) 131             { 132                 lock (_queue) 133                 { 134                     info = _queue.Dequeue(); 135                 } 136             } 137             return info; 138         } 139  140         /// <summary> 141         /// 監聽事件觸發的方法 142         /// </summary> 143         /// <param name="sender"></param> 144         /// <param name="e"></param> 145         private void OnProcess(object sender, FileSystemEventArgs e) 146         { 147             try 148             { 149                 FileChangeType changeType = FileChangeType.Unknow; 150                 if (e.ChangeType == WatcherChangeTypes.Created) 151                 { 152                     if (File.GetAttributes(e.FullPath) == FileAttributes.Directory) 153                     { 154                         changeType = FileChangeType.NewFolder; 155                     } 156                     else 157                     { 158                         changeType = FileChangeType.NewFile; 159                     } 160                 } 161                 else if (e.ChangeType == WatcherChangeTypes.Changed) 162                 { 163                     //部分文件創建時同樣觸發文件變化事件,此時記錄變化操作沒有意義 164                     //如果 165                     if (_queue.SelectAll( 166                         delegate(FileChangeInformation fcm) 167                         { 168                             return fcm.NewPath == e.FullPath && fcm.ChangeType == FileChangeType.Change; 169                         }).Count<FileChangeInformation>() > 0) 170                     { 171                         return; 172                     } 173  174                     //文件夾的變化,只針對創建,重命名和刪除動作,修改不做任何操作。 175                     //因為文件夾下任何變化同樣會觸發文件的修改操作,沒有任何意義. 176                     if (File.GetAttributes(e.FullPath) == FileAttributes.Directory) 177                     { 178                         return; 179                     } 180  181                     changeType = FileChangeType.Change; 182                 } 183                 else if (e.ChangeType == WatcherChangeTypes.Deleted) 184                 { 185                     changeType = FileChangeType.Delete; 186                 } 187  188                 //創建消息,並壓入隊列中 189                 FileChangeInformation info = new FileChangeInformation(Guid.NewGuid().ToString(), changeType, e.FullPath, e.FullPath, e.Name, e.Name); 190                 _queue.Enqueue(info); 191             } 192             catch 193             { 194                 Close(); 195             } 196         } 197  198         /// <summary> 199         /// 文件或目錄重命名時觸發的事件 200         /// </summary> 201         /// <param name="sender"></param> 202         /// <param name="e"></param> 203         private void OnFileRenamed(object sender, RenamedEventArgs e) 204         { 205             try 206             { 207                 //創建消息,並壓入隊列中 208                 FileChangeInformation info = new FileChangeInformation(Guid.NewGuid().ToString(), FileChangeType.Rename, e.OldFullPath, e.FullPath, e.OldName, e.Name); 209                 _queue.Enqueue(info); 210             } 211             catch 212             { 213                 Close(); 214             } 215         } 216     } 復制代碼   最後,功能調用如下:   復制代碼  1 //初始化監控器  2                 FileWatcher watcher = new FileWatcher(@"D:\");  3                 watcher.Open();  4   5                 FileChangeInformation fci = null;  6                 //獲取消息  7                 while (true)  8                 {  9                     //如果IsWatch為False,則可能監控內部發生異常終止了監控,需要重新開啟監控 10                     if (watcher.IsWatch) 11                     { 12                         //隊列頂端的變更消息 13                         fci = watcher.Get(); 14                         //處理消息的代碼 15                         //Print(fci); 16                     } 17                     else 18                     { 19                         watcher.Open(); 20                     } 21                     Thread.Sleep(1000); 22                 } 復制代碼   該程序實現了對文件目錄下所有子目錄和子文件的變化進行監控,並可通過FileChangeQueue屬性訪問文件變更消息,同時也可以設置其是否需要將數據持久化到磁盤文件中。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved