【发布时间】:2010-04-26 19:51:19
【问题描述】:
在 C# 中使用 FileSystemWatcher 监控多个文件夹(不是子目录)的最佳方法是什么?
【问题讨论】:
标签: c# .net filesystemwatcher
在 C# 中使用 FileSystemWatcher 监控多个文件夹(不是子目录)的最佳方法是什么?
【问题讨论】:
标签: c# .net filesystemwatcher
我认为 FSW 不支持监控多个文件夹,因此只需为每个要监控的文件夹实例化一个即可。不过,您可以将事件处理程序指向相同的方法,最终应该会像我认为的那样工作。
【讨论】:
最简单的方法是创建FileSystemWatcher 对象的多个实例。
http://www.c-sharpcorner.com/UploadFile/mokhtarb2005/FSWatcherMB12052005063103AM/FSWatcherMB.aspx
您必须确保正确处理两个文件夹之间的事件:
虽然有一些常见的情况,例如 作为复制或移动文件,不要 直接对应一个事件,这些 发生确实导致事件 提高。复制文件时, 系统在 文件复制到的目录 但不会引发任何事件 原目录。当你移动一个 文件,服务器引发两个事件: 源目录中的已删除事件, 紧随其后的是 Created 事件 目标目录。
例如,您创建两个实例 FileSystemWatcher 的。 FileSystemWatcher1 设置为监视 “C:\我的文档”,和 FileSystemWatcher2 设置为监视 “C:\您的文档”。现在,如果你复制 将“我的文档”中的文件放入“您的 Documents”,一个 Created 事件将是 由 FileSystemWatcher2 提出,但没有 事件为 文件系统观察器 1。不同于抄袭, 移动文件或目录会引发 两个事件。从前面的例子中, 如果您从“我的 文件”到“您的文件”,一个 创建的事件将由 FileSystemWatcher2 和 Deleted 事件 将由 FileSystemWatcher 引发
【讨论】:
开箱即用,FileSystemWatcher 仅支持监视单个父目录。要监控多个同级目录,您需要创建多个 FileSystemWatcher 实例。
但是,您可以尝试利用 FileSystemWatcher 包含子目录的能力来欺骗这种行为。您可以从您正在观看的目录创建一个 NTFS 连接点(又名符号链接)作为子目录。 Sysinternals 的 Mark Russinovich 有一个名为 Junction 的实用程序来简化符号链接的创建和管理。
请注意,您只能在本地计算机上创建指向目录的符号链接。
【讨论】:
虽然这是一个老问题,但我决定回答,因为我在任何地方都找不到好的答案。
那么,目标是使用 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);
}
}
}
【讨论】:
您可以简单地使用 FileSystemWatcher 的多个实例,每个目录一个吗?
【讨论】:
您必须实例化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;
【讨论】:
【讨论】: