2014年12月2日 星期二

如何使用FileWatching 監控某資料夾的檔案是否改變

   window form 的程式好手們,一定對它非常熟悉,因為某案子的需求需要用它來監控檔案是否有變化,為了讓更多朋友瞭解在哪種時機使用它,以下是程式範例和說明

 步驟一: 宣告變數
bool bolChanged; //稍後在說明,此變數的用途
 WrittingEventLog writeObj = new WriteEvent.WrittingEventLog();
 FileSystemWatcher _watchFolder = new FileSystemWatcher();
string strReadParamCooperCategory = System.IO.Directory.GetCurrentDirectory()+"\\"; //資料夾目錄路徑
 string strReadParamCooperFile = "*.*";  //可以指定檔名,若不指定檔案,就監控整個目錄

  步驟二: 註冊監控事件
     _watchFolder.NotifyFilter: 針對檔案的哪種變化來觸發事

  相關更多NotifyFilter 屬性請參考 

   public Form1()
        {
            InitializeComponent();           
            _watchFolder.Path = strReadParamCooperCategory; 指定監控的目錄
            _watchFolder.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite; //可以指定哪種檔案的變化
            _watchFolder.Filter = strReadParamCooperFile;
            _watchFolder.Changed += new FileSystemEventHandler(onChanged); //檔案修改時觸發事件
            _watchFolder.Created += new FileSystemEventHandler(onChanged); //檔案新增時觸發事件
            _watchFolder.Deleted += new FileSystemEventHandler(onChanged); //檔案刪除時觸發事件
            _watchFolder.EnableRaisingEvents = true; //啟動監控事件,少了這行…就無法監控檔案
            this.radDesktopAlert1.Popup.AlertElement.ContentElement.MouseDown += ContentElement_MouseDown;
            controlCallerObj.init();
        }

 步驟三: 觸發事件
   private void onChanged(object sender, System.IO.FileSystemEventArgs e)
        {
            _watchFolder.EnableRaisingEvents = false; //記得先停止動監控,以免觸發多次
            switch (e.ChangeType)
            {
                case WatcherChangeTypes.Changed: //測試資料夾的檔案(新增/修改/刪除)有變化
                    Thread myRun = new Thread(threadReadParametere); //啟動多執行緒
                    myRun.Start();
                    _watchFolder.EnableRaisingEvents = true; //執行完畢後,請再重新啟動監控
                    break;
                default:
                    break;
            }
        }

步驟四: 執行動作
        private void threadReadParametere()
        {
            try
            {
 strFileNames = Directory.GetFiles(System.IO.Directory.GetCurrentDirectory() + "\\telphone", "*.txt");  //有偵測資料夾.內的檔案有變化時,需要取得該目錄的所有檔案
                bolChanged = true; //告訴UI,目前要更新畫面
            }
            catch (Exception ex)
            {
                writeObj.writeToFile("threadReadParametere 錯誤:" + ex.Message);
            }
        }

步驟四: 呈在UI的畫面
private void timer1_Tick(object sender, EventArgs e)
        {
            if(bolChanged) //如有有變化,執行以下程式
            {
                string[] strFileData;
                radDesktopAlert1.ContentText = "<html>";
                foreach (string strFileName in strFileNames)
                {
                    strFileData = strFileName.Split('\\');
                    radDesktopAlert1.ContentText += "<size=20>" + changeText(strFileName) +"<br>";                   
                }
                radDesktopAlert1.ContentText += "</html>";
                radDesktopAlert1.Show();
                bolChanged = false; //執行完後,改變其狀態,才不會重複執行
            }
        }

步驟五: 結果
 監控的資料夾,如有檔案新增/刪除/修改















就會自動跳出提示訊息,並顯示相關訊息




















補充說明: 目前確定 FileSystemWatch 會連續觸發兩次的事件,但已經有高手針對這bug 另外做了一隻 FileSystemSafeWatcher 的類別,會自動過濾重複觸發的事件

https://github.com/melenaos/FileSystemSafeWatcher/blob/master/FileSystemSafeWatcher.cs




沒有留言:

張貼留言