FileWatcher.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. //************************************************************************
  2. // https://github.com/yuzhengyang
  3. // author: yuzhengyang
  4. // date: 2017.6.28 - 2017.6.29
  5. // desc: 文件变更监测
  6. // Copyright (c) yuzhengyang. All rights reserved.
  7. //************************************************************************
  8. using System;
  9. using System.Collections.Concurrent;
  10. using System.Collections.Generic;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. using Y.Utils.DataUtils.Collections;
  17. namespace Y.Utils.IOUtils.FileManUtils
  18. {
  19. /// <summary>
  20. /// 文件更改通知
  21. /// </summary>
  22. public class FileWatcher
  23. {
  24. /// <summary>
  25. /// 接受文件监控信息的事件委托
  26. /// </summary>
  27. /// <param name="sender"></param>
  28. /// <param name="args"></param>
  29. public delegate void FileWatcherEventHandler(object sender, FileWatcherEventArgs args);
  30. /// <summary>
  31. /// 获取文件监控信息
  32. /// </summary>
  33. public FileWatcherEventHandler EventHandler;
  34. private int Interval = 10 * 1000;
  35. private bool _IsWatching = false;
  36. private ConcurrentDictionary<string, FileSystemWatcher> Watchers = new ConcurrentDictionary<string, FileSystemWatcher>();
  37. /// <summary>
  38. /// 文件更改监控已启动
  39. /// </summary>
  40. public bool IsWatching { get { return _IsWatching; } }
  41. /// <summary>
  42. /// 创建文件监控类
  43. /// </summary>
  44. /// <param name="paths"></param>
  45. public FileWatcher(string[] paths)
  46. {
  47. if (ListTool.HasElements(paths))
  48. {
  49. foreach (var p in paths)
  50. {
  51. if (Directory.Exists(p) && !Watchers.ContainsKey(p))
  52. Watchers.TryAdd(p, null);
  53. }
  54. }
  55. }
  56. public bool AddPath(string path)
  57. {
  58. if (Directory.Exists(path) && !Watchers.ContainsKey(path))
  59. return Watchers.TryAdd(path, null);
  60. return false;
  61. }
  62. public bool DelPath(string path)
  63. {
  64. if (Watchers.ContainsKey(path))
  65. {
  66. FileSystemWatcher temp;
  67. if (Watchers.TryRemove(path, out temp) && temp != null)
  68. {
  69. temp.EnableRaisingEvents = false;
  70. temp.Dispose();
  71. return true;
  72. }
  73. }
  74. return false;
  75. }
  76. /// <summary>
  77. /// 启动文件监测
  78. /// </summary>
  79. public void Start()
  80. {
  81. if (!_IsWatching)
  82. {
  83. _IsWatching = true;
  84. Task.Factory.StartNew(() =>
  85. {
  86. while (_IsWatching)
  87. {
  88. foreach (var item in Watchers)
  89. {
  90. if (item.Value == null)
  91. {
  92. if (Directory.Exists(item.Key))
  93. {
  94. Watchers.TryUpdate(item.Key, CreateWatcher(item.Key), null);
  95. }
  96. }
  97. else
  98. {
  99. if (!Directory.Exists(item.Key))
  100. {
  101. item.Value.EnableRaisingEvents = false;
  102. item.Value.Dispose();
  103. Watchers.TryUpdate(item.Key, null, item.Value);
  104. }
  105. }
  106. }
  107. Thread.Sleep(Interval);
  108. }
  109. _IsWatching = false;
  110. });
  111. }
  112. }
  113. /// <summary>
  114. /// 停止文件监测
  115. /// </summary>
  116. public void Stop()
  117. {
  118. _IsWatching = false;
  119. foreach (var item in Watchers.Keys)
  120. {
  121. if (Watchers.ContainsKey(item))
  122. {
  123. if (Watchers[item] != null) Watchers[item].EnableRaisingEvents = false;
  124. FileSystemWatcher temp;
  125. if (Watchers.TryRemove(item, out temp) && temp != null)
  126. {
  127. temp.EnableRaisingEvents = false;
  128. temp.Dispose();
  129. }
  130. }
  131. }
  132. }
  133. private FileSystemWatcher CreateWatcher(string path)
  134. {
  135. FileSystemWatcher fsw = new FileSystemWatcher(path);
  136. fsw.Created += CreatedEvent;//创建文件或目录
  137. fsw.Changed += ChangedEvent;//更改文件或目录
  138. fsw.Deleted += DeletedEvent;//删除文件或目录
  139. fsw.Renamed += RenamedEvent;//重命名文件或目录
  140. fsw.Error += ErrorEvent;
  141. fsw.IncludeSubdirectories = true;
  142. fsw.NotifyFilter = (NotifyFilters)383;
  143. fsw.EnableRaisingEvents = true;
  144. return fsw;
  145. }
  146. private void CreatedEvent(object sender, FileSystemEventArgs e)
  147. {
  148. EventHandler?.Invoke(sender, new FileWatcherEventArgs(e.ChangeType, e.FullPath, Path.GetFileName(e.FullPath), null, null));
  149. }
  150. private void ChangedEvent(object sender, FileSystemEventArgs e)
  151. {
  152. EventHandler?.Invoke(sender, new FileWatcherEventArgs(e.ChangeType, e.FullPath, Path.GetFileName(e.FullPath), null, null));
  153. }
  154. private void DeletedEvent(object sender, FileSystemEventArgs e)
  155. {
  156. EventHandler?.Invoke(sender, new FileWatcherEventArgs(e.ChangeType, e.FullPath, Path.GetFileName(e.FullPath), null, null));
  157. }
  158. private void RenamedEvent(object sender, RenamedEventArgs e)
  159. {
  160. EventHandler?.Invoke(sender, new FileWatcherEventArgs(e.ChangeType, e.FullPath, Path.GetFileName(e.FullPath), e.OldFullPath, e.OldName));
  161. }
  162. private void ErrorEvent(object sender, ErrorEventArgs e)
  163. { }
  164. }
  165. }