天天看點

C#程式設計,監視檔案或者檔案夾的變化的一種方法。使用FileSystemWatcher類,需要添加using System.IO引用。

使用FileSystemWatcher類,需要添加using System.IO引用。

FileSystemWatcher控件主要功能:

監控指定檔案或目錄的檔案的建立、删除、改動、重命名等活動。可以動态地定義需要監控的檔案類型及檔案屬性改動的類型。

1、常用的幾個基本屬性:

(1) Path :設定要監視的目錄的路徑。

(2) IncludeSubdirectories :設定是否級聯監視指定路徑中的子目錄。

(3) Filter :設定篩選字元串,用于确定在目錄中監視哪些類型的檔案。若要監視所有檔案中的更改,請将 Filter 屬性設定為空字元串 ("") 或使用通配符(“*.*”),若要監視文本檔案中的更改,請将 Filter 屬性設定為“*.txt”。

(4) NotifyFilter :設定檔案的哪些屬性的變動會觸發Changed事件,同時監控多個屬性變動可以按“或”組合。(預設值為 NotifyFilter.LastWrite | NotifyFilter.FileName | NotifyFilter.DirectoryName 組合)

子項: Attributes           --  檔案或檔案夾的屬性。  

             CreationTime   --  檔案或檔案夾的建立時間。  

             DirectoryName --  目錄名。(常用) 

             FileName          --  檔案名。 (常用)

             LastAccess       --  檔案或檔案夾上一次打開的日期。  

             LastWrite           --  上一次向檔案或檔案夾寫入内容的日期。  

             Security              --  檔案或檔案夾的安全設定。  

             Size                    --   檔案或檔案夾的大小。 (常用)

(5) EnableRaisingEvents :設定是否開始監控。(預設為false)

 2、常用的幾個事件:

Changed 當更改指定 Path 中的檔案和目錄時發生。
Created 當在指定 Path 中建立檔案和目錄時發生。
Deleted 删除指定 Path 中的檔案或目錄時發生。
Disposed

當通過調用 Dispose() 方法釋放元件時發生。

(Inherited from Component)

Error 當 FileSystemWatcher 的執行個體無法繼續監視更改或内部緩沖區溢出時發生。
Renamed 重命名指定 Path 中的檔案或目錄時發生。

另外:

(1) FileSystemEventArgs 對象和RenameEventArgs對象:

成員:Name:     擷取受影響的檔案或目錄的名稱。 注意:如果是級聯監控子目錄的話,該值為從監控目錄的下個目錄到受影響的檔案的路徑,而不隻是受影響的檔案名。

            FullPath : 擷取受影響的檔案或目錄的完全限定的路徑。 

            ChangeType :擷取受影響的檔案或目錄的發生的事件類型。

子項:All    -- 檔案或檔案夾的建立、删除、更改或重命名。  

           Changed     -- 檔案或檔案夾的更改。更改的類型包括大小、屬性、安全設定、最近寫入時間和最近通路時間 

             Created       -- 檔案或檔案夾的建立。  

             Deleted       --  檔案或檔案夾的删除。  

             Renamed   --  檔案或檔案夾的重命名。

 3、注意緩沖區溢出:

 Windows 作業系統在 FileSystemWatcher 建立的緩沖區中通知元件檔案發生更改。如果短時間内有很多更改,則緩沖區可能會溢出。這将導緻元件失去對目錄更改的跟蹤,并且它将隻提供一般性通知。使用 InternalBufferSize 屬性來增加緩沖區大小的開銷較大,因為它來自無法換出到磁盤的非頁面記憶體,是以應確定緩沖區大小适中(盡量小,但也要有足夠大小以便不會丢失任何檔案更改事件)。若要避免緩沖區溢出,請使用 NotifyFilter 和 IncludeSubdirectories 屬性,以便可以篩選掉不想要的更改通知。

  使用 FileSystemWatcher 類時,請注意以下事項。

  1) 對包括隐藏檔案(夾)在内的所有檔案(夾)進行監控。

  2) 您可以為 InternalBufferSize 屬性(用于監視網絡上的目錄)設定的最大大小為 64 KB。

4、 注意權限:

由于檔案夾的檢測是以會觸及到系統安全,是以在程式之中程式的權限設定就顯得很有必要,在程式之中加入下面的代碼,能有效地避免程式被誤認為是非法操作。

[PermissionSetAttribute(SecurityAction.Demand, Name ="FullTrust")]
           

 5、注意線程:

     1)因為FileSystemWatcher類本身就是多線程的控件,也就是每執行個體化一個FileSystemWatcher自動就會建立一條線程。

     2)我們需要利用委托進行跨線程更新UI界面,因為重命名事件傳遞的是RenameEventArgs對象,而建立、修改、删除事件傳遞的是FileEventArgs對象,是以需要聲明兩個委托。

    3)如果需要同時監控多個檔案(如監控系統全盤),隻需要建立FileSystemWatcher數組,每個檔案用一個FileSystemWatcher進行監控。

6、控制台事例代碼:

private static void WatcherStrat(string path, string filter)
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = path;//設定監控的檔案目錄
            watcher.Filter = filter;//設定監控檔案的類型"*.txt|*.doc|*.jpg"
            watcher.Changed += new FileSystemEventHandler(OnProcess);
            watcher.Created += new FileSystemEventHandler(OnProcess);
            watcher.Deleted += new FileSystemEventHandler(OnProcess);
            watcher.Renamed += new RenamedEventHandler(OnRenamed);
            watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;
            watcher.IncludeSubdirectories = true;//設定監控C槽目錄下的所有子目錄
            watcher.EnableRaisingEvents = true;//啟動監控
        }



 private static void OnProcess(object source, FileSystemEventArgs e)
        {
            if (e.ChangeType == WatcherChangeTypes.Created)
            {
                OnCreated(source, e);
            }
            else if (e.ChangeType == WatcherChangeTypes.Changed)
            {
                OnChanged(source, e);
            }
            else if (e.ChangeType == WatcherChangeTypes.Deleted)
            {
                OnDeleted(source, e);
            }

        }



 private static void OnCreated(object source, FileSystemEventArgs e)
        {
            Console.WriteLine("檔案建立事件處理邏輯 {0}  {1}  {2}", e.ChangeType, e.FullPath, e.Name);
            
        }
       
        private static void OnChanged(object source, FileSystemEventArgs e)
        {
            Console.WriteLine("檔案改變事件處理邏輯{0}  {1}  {2}", e.ChangeType, e.FullPath, e.Name);
        }

        private static void OnDeleted(object source, FileSystemEventArgs e)
        {
            Console.WriteLine("檔案删除事件處理邏輯{0}  {1}   {2}", e.ChangeType, e.FullPath, e.Name);
        }

        private static void OnRenamed(object source, RenamedEventArgs e)
        {
            Console.WriteLine("檔案重命名事件處理邏輯{0}  {1}  {2}", e.ChangeType, e.FullPath, e.Name);
            
        }
           

 7、WPF下要考慮線程:

//聲明傳遞FileSystemEventArgs對象的委托,用于檔案Created,Deleted和Changed變動時更新UI界面。
        private delegate void setLogTextDelegate(FileSystemEventArgs e);
        //聲明傳遞RenamedEventArgs對象的委托,用于檔案Renamed時更新UI界面。
        private delegate void renamedDelegate(RenamedEventArgs e);  

        private static void WatcherStrat(string path, string filter)
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = path;//設定監控的檔案目錄
            watcher.Filter = filter;//設定監控檔案的類型"*.txt|*.doc|*.jpg"
            watcher.Changed += new FileSystemEventHandler(OnProcess);
            watcher.Created += new FileSystemEventHandler(OnProcess);
            watcher.Deleted += new FileSystemEventHandler(OnProcess);
            watcher.Renamed += new RenamedEventHandler(OnRenamed);
            watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;
            watcher.IncludeSubdirectories = true;//設定監控C槽目錄下的所有子目錄
            watcher.EnableRaisingEvents = true;//啟動監控
        }



        private static void OnProcess(object source, FileSystemEventArgs e)
        {
            if (e.ChangeType == WatcherChangeTypes.Created)
            {
                OnCreated(source, e);
            }
            else if (e.ChangeType == WatcherChangeTypes.Changed)
            {
                OnChanged(source, e);
            }
            else if (e.ChangeType == WatcherChangeTypes.Deleted)
            {
                OnDeleted(source, e);
            }

        }
        private static void OnCreated(object source, FileSystemEventArgs e)
        {
            
            if (this.控件名.InvokeRequired)  //判斷是否跨線程
            {
                this.控件名.Invoke(new setLogTextDelegate(setLogText), new object[] { e });   //使用委托将方法封送到UI主線程處理
            }
        }
        private void setLogText(FileSystemEventArgs e)  //更新UI界面
        {
            this.控件名.text=e.Name;
        }
        private static void OnChanged(object source, FileSystemEventArgs e)
        {
           
        }

        private static void OnDeleted(object source, FileSystemEventArgs e)
        {
            
        }

        private static void OnRenamed(object source, RenamedEventArgs e)
        {
            
            if (this.控件名.InvokeRequired) //判斷是否跨線程
            {
                this.控件名.Invoke(new renamedDelegate(setRenamedLogText), new object[] { e });  //使用委托将方法封送到UI主線程處理
            }
        }
        private void setRenamedLogText(FileSystemEventArgs e)  //更新UI界面
        {
            this.控件名.text = e.Name;
        }