文件系统观察器 - 不仅观察文件而且观察内部文件
Posted
技术标签:
【中文标题】文件系统观察器 - 不仅观察文件而且观察内部文件【英文标题】:File System Watcher - watch not only file but also inside file 【发布时间】:2022-01-13 08:01:25 【问题描述】:如何使用 FileSystemWatcher 监控文件中的更改
我有一个包含疾病的文件夹,我想在控制台上不仅显示包中的更改,还显示文件(例如 .txt .doc ...)中的更改 我使用事件(创建删除更改),但它仅适用于文件夹,不适用于文件内
【问题讨论】:
所以你想做某种文件差异? 它只适用于文件夹,而不适用于文件内部 - 但编辑文件的最后写入时间会发生变化,FSW 会选择它.. ? FSW 不会告诉您文件内部发生了哪些更改,只会告诉您文件已更改。要么自己保留文件的副本,并在每次看到更改时对其进行比较.. 或者使用 git 之类的东西来查看更改 @TheGeneral 我想输出到控制台,例如(文件中的文本现在写入)更改(现在不写入文本)并且此更改专用并输出 @CaiusJard 不能将文件中的变化实时显示到控制台吗?? 【参考方案1】:您可以从文件中获取副本作为历史回购,并在需要时从中获取旧内容
来自original example的修改示例
class MyClassCS
static HelperRepo repo;
static void Main()
string SrcDir = @"D:\XRep";
using var watcher = new FileSystemWatcher(SrcDir);
repo = new HelperRepo(SrcDir); // repo for history changes
watcher.NotifyFilter = NotifyFilters.Attributes
| NotifyFilters.CreationTime
| NotifyFilters.DirectoryName
| NotifyFilters.FileName
| NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.Security
| NotifyFilters.Size;
watcher.Changed += OnChanged;
watcher.Created += OnCreated;
watcher.Deleted += OnDeleted;
watcher.Renamed += OnRenamed;
watcher.Error += OnError;
watcher.Filter = "*.txt";
watcher.IncludeSubdirectories = true;
watcher.EnableRaisingEvents = true;
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
private static void OnChanged(object sender, FileSystemEventArgs e)
if (e.ChangeType != WatcherChangeTypes.Changed)
return;
Console.WriteLine($"Changed: e.FullPath");
// you can see the diff from your repo
var oldContent = repo.GetFileContent(e.FullPath);
var newContet = File.ReadAllText(e.FullPath);
Console.WriteLine($"new Content : newContet");
Console.WriteLine($"old Content: oldContent");
// reflect change in repo
repo.ReflectFile(e.FullPath);
private static void OnCreated(object sender, FileSystemEventArgs e)
string value = $"Created: e.FullPath";
Console.WriteLine(value);
// reflect change in repo
repo.ReflectFile(e.FullPath);
private static void OnDeleted(object sender, FileSystemEventArgs e)
Console.WriteLine($"Deleted: e.FullPath");
// reflect change in repo
repo.ReflectDelet(e.FullPath);
private static void OnRenamed(object sender, RenamedEventArgs e)
Console.WriteLine($"Renamed:");
Console.WriteLine($" Old: e.OldFullPath");
Console.WriteLine($" New: e.FullPath");
// reflect change in repo
repo.ReflectRename(e.OldFullPath, e.FullPath);
private static void OnError(object sender, ErrorEventArgs e) =>
PrintException(e.GetException());
private static void PrintException(Exception? ex)
if (ex != null)
Console.WriteLine($"Message: ex.Message");
Console.WriteLine("Stacktrace:");
Console.WriteLine(ex.StackTrace);
Console.WriteLine();
PrintException(ex.InnerException);
HelperRepo
class HelperRepo
private readonly string _repoDir = @"D:\temp_repo";
private readonly string _srcDir;
public HelperRepo(string srcDir)
Directory.CreateDirectory(srcDir); // make sure that repo exist
CopyFilesRecursively(srcDir, _repoDir);
_srcDir = srcDir;
public string GetFileContent(string src_File)
var dir = Path.GetDirectoryName(src_File) ?? "";
if (!dir.StartsWith(_srcDir))
throw new ArgumentException("inCorect Directory");
var repoFile = src_File.Replace(_srcDir, _repoDir);
return File.ReadAllText(repoFile);
public void ReflectFile(string src_File)
var dir = Path.GetDirectoryName(src_File) ?? "";
if (!dir.StartsWith(_srcDir))
throw new ArgumentException("inCorect Directory");
File.Copy(src_File, src_File.Replace(_srcDir, _repoDir), true);
public void ReflectDelet(string src_File)
var dir = Path.GetDirectoryName(src_File) ?? "";
if (!dir.StartsWith(_srcDir))
throw new ArgumentException("inCorect Directory");
File.Delete(src_File.Replace(_srcDir, _repoDir));
public void ReflectRename(string oldPath, string newPath)
ReflectDelet(oldPath);
ReflectFile(newPath);
static void CopyFilesRecursively(string sourcePath, string targetPath)
//Now Create all of the directories
foreach (string dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
Directory.CreateDirectory(dirPath.Replace(sourcePath, targetPath));
//Copy all the files & Replaces any files with the same name
foreach (string srcFile in Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories))
var targetFile = srcFile.Replace(sourcePath, targetPath);
File.Copy(srcFile, targetFile, true);
【讨论】:
以上是关于文件系统观察器 - 不仅观察文件而且观察内部文件的主要内容,如果未能解决你的问题,请参考以下文章
创建文件观察器,当特定文件被修改时将重新启动 websocket 服务器