偵聽Windows資料夾變更事件
阿新 • • 發佈:2019-01-06
通過以下兩個類,可以實現對windows資料夾的事件偵聽,包括新建檔案,刪除檔案,檔案重新命名等事件;
FileSystemWather.cs
WatcherProcess.csusing System; using System.Collections; using System.IO; using System.Threading; namespace Whir.Software.FileCopy { public delegate void Completed(string key); public class FileSystemWather { private readonly FileSystemWatcher _fsWather; private readonly Hashtable _hstbWather; /// <summary> /// 建構函式 /// </summary> /// <param name="path">要監控的路徑</param> /// <param name="filter">要監控的檔案</param> /// <param name="includeSubdirectories">是否包含子資料夾</param> public FileSystemWather(string path, string filter, bool includeSubdirectories) { if (!Directory.Exists(path)) { throw new Exception("找不到路徑:" + path); } _hstbWather = new Hashtable(); _fsWather = new FileSystemWatcher(path) {IncludeSubdirectories = includeSubdirectories, Filter = filter}; _fsWather.Renamed += fsWather_Renamed; _fsWather.Changed += fsWather_Changed; _fsWather.Created += fsWather_Created; _fsWather.Deleted += fsWather_Deleted; } public event RenamedEventHandler OnRenamed; public event FileSystemEventHandler OnChanged; public event FileSystemEventHandler OnCreated; public event FileSystemEventHandler OnDeleted; /// <summary> /// 開始監控 /// </summary> public void Start() { _fsWather.EnableRaisingEvents = true; } /// <summary> /// 停止監控 /// </summary> public void Stop() { _fsWather.EnableRaisingEvents = false; } /// <summary> /// filesystemWatcher 本身的事件通知處理過程 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void fsWather_Renamed(object sender, RenamedEventArgs e) { lock (_hstbWather) { if (!_hstbWather.ContainsKey(e.FullPath)) { _hstbWather.Add(e.FullPath, e); } } var watcherProcess = new WatcherProcess(sender, e); watcherProcess.OnRenamed += OnRenamed; //傳遞事件 watcherProcess.OnCompleted += WatcherProcess_OnCompleted; var thread = new Thread(watcherProcess.Process); thread.Start(); } private void fsWather_Created(object sender, FileSystemEventArgs e) { lock (_hstbWather) { if (!_hstbWather.ContainsKey(e.FullPath)) { _hstbWather.Add(e.FullPath, e); } } var watcherProcess = new WatcherProcess(sender, e); watcherProcess.OnCreated += OnCreated; //傳遞事件 watcherProcess.OnCompleted += WatcherProcess_OnCompleted; var threadDeal = new Thread(watcherProcess.Process); threadDeal.Start(); } private void fsWather_Deleted(object sender, FileSystemEventArgs e) { lock (_hstbWather) { if (!_hstbWather.ContainsKey(e.FullPath)) { _hstbWather.Add(e.FullPath, e); } } var watcherProcess = new WatcherProcess(sender, e); watcherProcess.OnDeleted += OnDeleted; //傳遞事件 watcherProcess.OnCompleted += WatcherProcess_OnCompleted; var tdDeal = new Thread(watcherProcess.Process); tdDeal.Start(); } private void fsWather_Changed(object sender, FileSystemEventArgs e) { if (e.ChangeType == WatcherChangeTypes.Changed) { if (_hstbWather.ContainsKey(e.FullPath)) { WatcherChangeTypes oldType = ((FileSystemEventArgs) _hstbWather[e.FullPath]).ChangeType; if (oldType == WatcherChangeTypes.Created || oldType == WatcherChangeTypes.Changed) { return; } } } lock (_hstbWather) { if (!_hstbWather.ContainsKey(e.FullPath)) { _hstbWather.Add(e.FullPath, e); } } var watcherProcess = new WatcherProcess(sender, e); watcherProcess.OnChanged += OnChanged; //傳遞事件 watcherProcess.OnCompleted += WatcherProcess_OnCompleted; var thread = new Thread(watcherProcess.Process); thread.Start(); } /// <summary> /// 使用了執行緒安全的Hashtable來處理一次改變觸發兩次事件的問題, /// 要注意的是在實際專案使用中,在通過監控檔案事情觸發時開一個執行緒WatcherProcess去處理自己業務邏輯的時候, /// 不管業務邏輯成功或者失敗(例如有異常丟擲一定要try一下)一定要讓WatcherProcess的Completed /// 也就是MyFileSystemWather的WatcherProcess_OnCompleted執行去移除對應變化檔案的Hashtable的key, /// 不然下次此檔案改變時是無法觸發你的業務邏輯的。 /// </summary> /// <param name="key"></param> public void WatcherProcess_OnCompleted(string key) { lock (_hstbWather) { _hstbWather.Remove(key); } } } }
使用方法:using System.IO; namespace Whir.Software.FileCopy { public class WatcherProcess { private readonly object _eParam; private readonly object _sender; public WatcherProcess(object sender, object eParam) { _sender = sender; _eParam = eParam; } public event RenamedEventHandler OnRenamed; public event FileSystemEventHandler OnChanged; public event FileSystemEventHandler OnCreated; public event FileSystemEventHandler OnDeleted; public event Completed OnCompleted; public void Process() { if (_eParam.GetType() == typeof (RenamedEventArgs)) { OnRenamed(_sender, (RenamedEventArgs) _eParam); OnCompleted(((RenamedEventArgs) _eParam).FullPath); } else { var e = (FileSystemEventArgs) _eParam; if (e.ChangeType == WatcherChangeTypes.Created) { OnCreated(_sender, e); OnCompleted(e.FullPath); } else if (e.ChangeType == WatcherChangeTypes.Changed) { OnChanged(_sender, e); OnCompleted(e.FullPath); } else if (e.ChangeType == WatcherChangeTypes.Deleted) { OnDeleted(_sender, e); OnCompleted(e.FullPath); } else { OnCompleted(e.FullPath); } } } } }
var wather = new FileSystemWather(TxtFrom.Text, "*.*", true);
wather.OnChanged += OnChanged;
wather.OnCreated += OnCreated;
wather.OnRenamed += OnRenamed;
wather.OnDeleted += OnDeleted;
wather.Start();
對應事件響應:
private void OnCreated(object source, FileSystemEventArgs e) { //檔案全路徑:e.FullPath //檔名:e.Name //事件型別: e.ChangeType //自定義邏輯處理 } private void OnChanged(object source, FileSystemEventArgs e) { //自定義邏輯處理 } private void OnDeleted(object source, FileSystemEventArgs e) { //自定義邏輯處理 } private void OnRenamed(object source, RenamedEventArgs e) { //自定義邏輯處理 }