【问题标题】:How to write FileSystemWatcher without triggering an infinite loop如何在不触发无限循环的情况下编写 FileSystemWatcher
【发布时间】:2018-05-31 15:59:40
【问题描述】:

如何将 C# 中的文件写入 FileSystemWatcher 监视的文件夹路径?

我的fileSystemWatcher设置如下:

public FileSystemWatcher CreateAndExecute(string path)
{
    Console.WriteLine("Watching " + path);

    //Create new watcher
    FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();

    fileSystemWatcher.Path = path;
    fileSystemWatcher.IncludeSubdirectories = false;
    fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite | 
    NotifyFilters.FileName | NotifyFilters.DirectoryName;

    fileSystemWatcher.Filter = "*.txt";
    fileSystemWatcher.Changed += new FileSystemEventHandler(OnChange);

    fileSystemWatcher.InternalBufferSize = 32768;

    //Execute
    fileSystemWatcher.EnableRaisingEvents = true;
}

private void OnChange(object source, FileSystemEventArgs e)
{
    //Replace modified file with original copy
}

每当文件发生未经授权的写入(程序外)时,我想用数据库中的备份副本替换已修改文件的内容。

但是,当我使用 File.WriteAllText() 写入修改后的文件时,它会触发 FileSystemWatcher 的 Change 事件,因为该操作再次注册为写入。

这会导致程序在覆盖它刚刚写入的文件的无限循环中运行。

如何在不触发 FileSystemWatcher 写入另一个事件的情况下将修改后的文件替换为备份副本?

【问题讨论】:

  • 态度好吗?你不能。检测它,保留您已恢复的文件的列表并注意随后的事件,或检测您刚刚检测到写入的文件正是它应有的状态,因此无需采取任何措施。
  • 能否在 OnChange 事件触发后取消绑定,然后在写入文件后重新绑定?尽管存在未绑定时您会丢失文件的危险。只是一个想法。
  • 您说的是“来自数据库”,这让我怀疑这些文件旨在供特定应用程序使用。如果是这样,那么是否有可能,而不是将文件保存在磁盘上,应用程序从数据库中获取,做任何事情(并且可能在完成后擦除)。
  • OnChange的第一行设置fileSystemWatcher.EnableRaisingEvents = false;,在File.WriteAllText()之后设置为true怎么样?
  • 你为什么要这样做?为什么程序不直接从数据库中读取文件?为什么它们必须存在于磁盘上?另外,如果它们不应该被任何人修改,为什么不将其安装在不允许其他任何人修改它们的用户下呢?操作系统中已经有一些很好的方法,比如 ACL,可以处理这种情况。请注意,“有效”参数是管理员可以轻松绕过 ACL,但它是无效的,因为同一管理员可以轻松杀死您的备份监视器。

标签: c# filesystemwatcher


【解决方案1】:

除了您可以通过使用操作系统文件安全性 f.e. 以更好/不同的方式解决问题之外,您还有一些选择:

  • 暂时禁用观察程序,在这种情况下,您可以在暴力攻击时丢失事件,这可能不是您想要的。
  • 保留一份包含已重写文件的列表,忽略列表中文件的一项更改,然后将其从列表中删除 -> 如果恶意程序知道这一点,也可能被滥用
  • 存储文件内容的 SHA1 或 SHA256(或其他哈希),并且仅在哈希不同时替换文件 -> 可能是解决此问题的最佳方法

【讨论】:

  • 谢谢!我认为暂时禁用观察者应该没问题。有一个令牌机制,所以禁用一段时间应该没问题
猜你喜欢
  • 1970-01-01
  • 2012-01-31
  • 1970-01-01
  • 2017-11-22
  • 1970-01-01
  • 2021-06-08
  • 2013-03-23
  • 2019-05-27
  • 1970-01-01
相关资源
最近更新 更多