C# 文件监视 FileSystemWatcher

// 官方帮助 Console: https://learn.microsoft.com/zh-cn/dotnet/api/system.io.filesystemwatcher?view=net-8.0
// 官方帮助 WPF:     https://learn.microsoft.com/zh-cn/dotnet/fundamentals/runtime-libraries/system-io-filesystemwatcher
/* FileSysytemWatcher类 介绍
用于 FileSystemWatcher 监视指定目录中的更改。 可以监视指定目录的文件和子目录中的更改。 可以创建一个组件来监视本地计算机、网络驱动器或远程计算机上的文件。
若要监视所有文件中的更改,请将Filter属性设置为空字符串(“”“)或使用 wild卡s(”*.*“)。 若要监视特定文件,请将 Filter 属性设置为文件名。 例如,若要监视文件MyDoc.txt中的更改,请将 Filter 属性设置为“MyDoc.txt”。 还可以监视特定类型文件中的更改。 例如,若要监视文本文件中的更改,请将 Filter 属性设置为“*.txt”。
可以在目录或文件中监视多种类型的更改。 例如,可以监视文件或目录的 Attributes更改、 LastWrite 日期和时间或 Size 目录。 通过将属性设置为 NotifyFilter 其中 NotifyFilters 一个值来完成此操作。 有关可监视的更改类型的详细信息,请参阅 NotifyFilters。
可以监视文件或目录的重命名、删除或创建。 例如,若要监视文本文件的重命名,请将 Filter 属性设置为“*.txt”,并使用为其参数指定的方法来调用 WaitForChanged 该方法 Renamed 。
Windows 操作系统会通知组件文件更改的缓冲区。FileSystemWatcher 如果短时间内发生了许多更改,缓冲区可能会溢出。 这会导致组件失去对目录中的更改的跟踪,并且只会提供全面通知。 使用 InternalBufferSize 属性增加缓冲区的大小非常昂贵,因为它来自无法交换到磁盘的非分页内存,因此请将缓冲区保留为小到大,无法错过任何文件更改事件。 若要避免缓冲区溢出,请使用 NotifyFilter 和 IncludeSubdirectories 属性,以便筛选掉不需要的更改通知。
*/
namespace ConsoleApp_FileSysytemWatcher
{
    internal class Program
    {
        static void Main(string[] args)
        {
            FileSystemWatch();
        }

        // 目录路径
        public static string p = "D:/WatcherFile";
          

        static void FileSystemWatch() 
        {

            // 可以根据选择的文件类型处理
            string filez = "";
            switch(filez)
            {
                case ("txt"): filez = "*.txt"; break;
                case ("bmp"): filez = "*.bmp"; break;
                default: filez = "*"; break;
            }
            
                
            
                
            FileSystemWatcher watcher = new FileSystemWatcher(p,filez); // 参数一: 目录路径 参数二: 指定约束文件,可使用通配符"*" 或 "*.txt"
            watcher.EnableRaisingEvents = true;     // 是否启用该控件
            watcher.IncludeSubdirectories = true;  // 是否监视子目录

            // 在循环体中监视文件状态
            while (true) 
            {
                var p = watcher.WaitForChanged(WatcherChangeTypes.All); // 再次循环会在此暂停, 会返回改变文件的信息.
                Console.WriteLine(p.OldName);  // 重命名之前的名称
                Console.WriteLine(p.Name);      // 文件名称
                Console.WriteLine(p.ChangeType);    // 文件操作类型
                                                    //Message();                          // 执行非事件方法, 只要循环一次就执行一次, 没有限制; 

                // [ 触发事件 ]
                // 有个问题, += 等于值的递归增值, 如字符串会自加
                // 但总感觉这样的做法很笨, 不知道有什么更有效的方法.
                watcher.Created -= OnChanged;
                watcher.Deleted -= Delete;

                watcher.Created += OnChanged;       // 文件被改变触发的事件 
                watcher.Deleted += Delete;
            }


            // 事件触发的方法需要添加 (object sender, FileSystemEventArgs e) 参数, 这是约定的;
            static void Delete(object sender, FileSystemEventArgs e)
            {                
                Console.WriteLine("你改删除了文件",e.Name);
            }

            static void Message()
            {
                Console.WriteLine("你改变了文件");
            }

            static void OnChanged(object sender, FileSystemEventArgs e) 
            {
                DirectoryInfo info  = new DirectoryInfo(p);
                foreach (FileInfo file in info.GetFiles()) { Console.WriteLine(file.FullName); }                
            }

            /* FileSystemWatcher总结
             * FileSystemWatcher 创建构造对象 填入路径和约定的文件类型
             * 然后再循环体中添加 WaitForChanged(WatcherChangeTypes)方法, 能够监控文件状态,
             * 而WatcherChangeTypes是枚举类型, 可以监控文件什么状态被监控.
             * 如果需要可以在循环体中再添加触发事件的方法.
             */

        }
    }
}

 

posted @ 2024-03-24 08:26  edolf  阅读(419)  评论(0编辑  收藏  举报