31

在 C# 中使用 FileSystemWatcher 监视多个文件夹(不是子目录)的最佳方法是什么?

4

7 回答 7

24

我认为 FSW 不支持监视多个文件夹,因此只需为每个要监视的文件夹实例化一个。不过,您可以将事件处理程序指向相同的方法,最终应该会像我认为的那样工作。

于 2010-04-26T19:54:02.923 回答
14

最简单的方法是创建FileSystemWatcher对象的多个实例。

http://www.c-sharpcorner.com/UploadFile/mokhtarb2005/FSWatcherMB12052005063103AM/FSWatcherMB.aspx

您必须确保正确处理两个文件夹之间的事件:

尽管一些常见的事件(例如复制或移动文件)并不直接对应于事件,但这些事件确实会引发事件。复制文件时,系统会在文件复制到的目录中引发 Created 事件,但不会在原始目录中引发任何事件。当您移动文件时,服务器会引发两个事件:源目录中的 Deleted 事件,然后是目标目录中的 Created 事件。

例如,您创建两个 FileSystemWatcher 实例。FileSystemWatcher1 设置为监视“C:\My Documents”,FileSystemWatcher2 设置为监视“C:\Your Documents”。现在,如果您将文件从“我的文档”复制到“您的文档”中,FileSystemWatcher2 将引发 Created 事件,但 FileSystemWatcher1 不会引发任何事件。与复制不同,移动文件或目录会引发两个事件。在前面的示例中,如果您将文件从“我的文档”移动到“您的文档”,FileSystemWatcher2 将引发 Created 事件,FileSystemWatcher 将引发 Deleted 事件

链接到FileSystemEventArgs

于 2010-04-26T19:54:45.800 回答
6

开箱即用,FileSystemWatcher 仅支持监视单个父目录。要监视多个同级目录,您需要创建多个 FileSystemWatcher 实例。

但是,您可以尝试利用 FileSystemWatcher 包含子目录的能力来欺骗这种行为。您可以从您正在观看的目录创建一个 NTFS 连接点(又名符号链接)作为子目录。Sysinternals 的 Mark Russinovich 有一个名为Junction的实用程序来简化符号链接的创建和管理。

请注意,您只能在本地计算机上创建指向目录的符号链接。

于 2010-04-26T20:14:55.307 回答
5

虽然这是一个老问题,但我决定回答,因为我在任何地方都找不到好的答案。

那么,目的是使用 FileSystemWatcher 监控多个文件夹(不是子目录)?这是我的建议:

using System;
using System.IO;
using System.Security.Permissions;
using System.Collections.Generic;

namespace MultiWatcher
// ConsoleApplication, which monitors TXT-files in multiple folders. 
// Inspired by:
// http://msdn.microsoft.com/en-us/library/system.io.filesystemeventargs(v=vs.100).aspx

{
    public class Watchers
    {
        public static void Main()
        {
            Run();

        }

        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        public static void Run()
        {
            string[] args = System.Environment.GetCommandLineArgs();

            // If a directory is not specified, exit program.
            if (args.Length < 2)
            {
                // Display the proper way to call the program.
                Console.WriteLine("Usage: Watcher.exe PATH [...] [PATH]";
                return;
            }
            List<string> list = new List<string>();
            for (int i = 1; i < args.Length; i++)
            {
                list.Add(args[i]);
            }
            foreach (string my_path in list)
            {
                Watch(my_path);
            }

            // Wait for the user to quit the program.
            Console.WriteLine("Press \'q\' to quit the sample.");
            while (Console.Read() != 'q') ;
        }
        private static void Watch(string watch_folder)
        {
            // Create a new FileSystemWatcher and set its properties.
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = watch_folder;
            /* Watch for changes in LastAccess and LastWrite times, and
               the renaming of files or directories. */
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
               | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            // Only watch text files.
            watcher.Filter = "*.txt";

            // Add event handlers.
            watcher.Changed += new FileSystemEventHandler(OnChanged);
            watcher.Created += new FileSystemEventHandler(OnChanged);
            watcher.Deleted += new FileSystemEventHandler(OnChanged);
            watcher.Renamed += new RenamedEventHandler(OnRenamed);

            // Begin watching.
            watcher.EnableRaisingEvents = true;
        }

        // Define the event handlers.
        private static void OnChanged(object source, FileSystemEventArgs e)
        {
            // Specify what is done when a file is changed, created, or deleted.
            Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
        }

        private static void OnRenamed(object source, RenamedEventArgs e)
        {
            // Specify what is done when a file is renamed.
            Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
        }
    }
}
于 2012-12-21T12:23:30.633 回答
3

您必须实例化FileSystemWatcher对象的多个实例。尽管您可以将事件绑定到相同的方法并使用发送者对象来确定是哪个FileSystemWatcher触发了事件。

        var fsw1 = new FileSystemWatcher();
        var fsw2 = new FileSystemWatcher();
        FileSystemEventHandler fsw_changed = delegate(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("{0} - {1}", (sender as FileSystemWatcher).Path, e.ChangeType);
        };
        fsw1.Changed += fsw_changed;
        fsw2.Changed += fsw_changed;
于 2010-04-26T20:40:28.733 回答
3

您可以简单地使用 FileSystemWatcher 的多个实例,每个目录一个吗?

于 2010-04-26T19:54:15.367 回答
0

或者您可以在代码中传递路径,以标记特定范围的域,如下所示:

多显示器链接

希望这可以帮助。

于 2012-12-21T03:53:55.463 回答