FileSystemWatcher 简单使用
这里看一个文件夹下监测的例子。
首先来看下MSDN上的备注信息。这里网址:http://msdn.microsoft.com/zh-cn/library/system.io.filesystemwatcher.aspx
使用 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 的实例的初始属性值列表,请参见 FileSystemWatcher 构造函数。
使用 FileSystemWatcher 类时,请注意以下事项。
-
不忽略隐藏文件。
-
在某些系统中,FileSystemWatcher 使用 8.3 短文件名格式报告文件更改。例如,为“LongFileName.LongExtension”更改可以报告为“LongFil~.Lon”。
-
此类在应用于所有成员的类级别上包含一个链接要求和一个继承要求。如果直接调用方或派生类不具有完全信任权限,则会引发 SecurityException。有关安全要求的详细信息,请参见 链接需求。
-
您可以为 InternalBufferSize 属性(用于监视网络上的目录)设置的最大大小为 64 KB。
这里自己结合官方写了个例子,里面肯定有很多东西没有想到,欢迎各位指正。
1 class Program 2 { 3 private static FileSystemWatcher watcher; 4 private static string logDir = (AppDomain.CurrentDomain.BaseDirectory); //get current project bin dir 5 private static string logFile = "Log"; 6 private static string sMonitorDir = @"D:\TDDOWNLOAD"; 7 private static string LogExt = "log"; // file suffix 8 9 static void Main(string[] args) 10 { 11 Run(); 12 } 13 [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] 14 public static void Run() 15 { 16 watcher = new FileSystemWatcher(); 17 18 //需要监测的文件路径,路径不存在则创建 19 DirectoryInfo di = new DirectoryInfo(sMonitorDir); 20 if (!di.Exists) 21 { 22 di.Create(); 23 } 24 watcher.Path = sMonitorDir; 25 //获取或设置要监视的更改类型。 26 watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName 27 | NotifyFilters.LastAccess | NotifyFilters.LastWrite; 28 watcher.IncludeSubdirectories = true; //是否包含子目录 29 watcher.Filter = "*.txt"; 30 31 watcher.Changed += new FileSystemEventHandler(OnChanged); 32 watcher.Created += new FileSystemEventHandler(OnChanged); 33 watcher.Deleted += new FileSystemEventHandler(OnChanged); 34 watcher.Renamed += new RenamedEventHandler(OnRenamed); 35 watcher.Error += new ErrorEventHandler(OnError); 36 37 watcher.EnableRaisingEvents = true; 38 39 Console.Read(); 40 } 41 42 //changeed,deleted,created. 43 static void OnChanged(object sender, FileSystemEventArgs e) 44 { 45 //先将EnableRaisingEvents设置为false然后处理完文件之后再设置为true即可避免触发多次问题。 46 watcher.EnableRaisingEvents = false; 47 //WatcherChangeTypes是一个枚举 48 if (WatcherChangeTypes.Changed == e.ChangeType) 49 { 50 Console.WriteLine("File is changed"); 51 } 52 if (WatcherChangeTypes.Created == e.ChangeType) 53 { 54 Console.WriteLine("File is Created"); 55 } 56 if (WatcherChangeTypes.Deleted == e.ChangeType) 57 { 58 Console.WriteLine("File is deleted"); 59 } 60 Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType); 61 WriteFile("File: " + e.FullPath + " " + e.ChangeType); 62 watcher.EnableRaisingEvents = true; 63 } 64 65 //renamed event 66 private static void OnRenamed(object source, RenamedEventArgs e) 67 { 68 watcher.EnableRaisingEvents = false; 69 if (WatcherChangeTypes.Renamed == e.ChangeType) 70 { 71 Console.WriteLine("File is renamed"); 72 73 } 74 Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath); 75 WriteFile("File: " + e.FullPath + " " + e.ChangeType); 76 watcher.EnableRaisingEvents = true; 77 78 } 79 private static void OnError(object source, ErrorEventArgs e) 80 { 81 Console.WriteLine("The FileSystemWatcher has detected an error"); 82 83 if (e.GetException().GetType() == typeof(InternalBufferOverflowException)) 84 { 85 Console.WriteLine(("The file system watcher experienced an internal buffer overflow: " + e.GetException().Message)); 86 WriteFile(("The file system watcher experienced an internal buffer overflow: " + e.GetException().Message)); 87 } 88 } 89 //write the message to file 90 private static void WriteFile(string sMessage) 91 { 92 try 93 { 94 Log logEntry = new Log(sMessage); 95 string logPath = Path.Combine(logDir, logFile, logEntry.LogDate + "." + LogExt); 96 if ((logPath.Length > 0) && (!Directory.Exists(logPath))) 97 { 98 Directory.CreateDirectory(Path.GetDirectoryName(logPath)); 99 } 100 // This could be optimised to prevent opening and closing the file for each write 101 using (FileStream fs = File.Open(logPath, FileMode.Append, FileAccess.Write)) 102 { 103 using (StreamWriter log = new StreamWriter(fs)) 104 { 105 log.WriteLine(string.Format("{0}\t{1}", logEntry.LogTime, logEntry.Message)); 106 } 107 } 108 } 109 catch (Exception ex) 110 { 111 throw ex; 112 } 113 } 114 } 115 /// <summary> 116 /// A Log class to store the message and the Date and Time the log entry was created 117 /// </summary> 118 public class Log 119 { 120 public string Message { get; set; } 121 public string LogTime { get; set; } 122 public string LogDate { get; set; } 123 public string LogFileName { get; set; } 124 public Log(string message) 125 { 126 Message = message; 127 DateTime curDT = DateTime.Now; 128 LogDate = curDT.ToString("yyyy-MM-dd"); 129 LogTime = curDT.ToString("hh:mm:ss.fff tt"); 130 LogFileName = curDT.ToString("yyyyMMddhhmmssfff"); 131 } 132 }