Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# FileSystemWatcher和监视配置文件更改_C#_Filesystemwatcher - Fatal编程技术网

C# FileSystemWatcher和监视配置文件更改

C# FileSystemWatcher和监视配置文件更改,c#,filesystemwatcher,C#,Filesystemwatcher,我有大约5-6个服务器管理器程序,它们将自己的配置文件写入一个特定的文件夹,例如C:\ACME。配置文件都以*ServerConfig.cfg“where*=创建它的程序名结尾 我有一个Windows服务,它有一个FileSystemWatcher设置,每次程序更新时我都想用FTP传输配置文件。我已经让所有的东西都正常工作了,但我注意到不同的服务器管理器程序的行为不同 在保存配置文件时,FileSystemWatcher会拾取两个“更改”事件。这会导致我的程序将配置文件FTP两次,而我只需要一次

我有大约5-6个服务器管理器程序,它们将自己的配置文件写入一个特定的文件夹,例如C:\ACME。配置文件都以*ServerConfig.cfg“where*=创建它的程序名结尾

我有一个Windows服务,它有一个FileSystemWatcher设置,每次程序更新时我都想用FTP传输配置文件。我已经让所有的东西都正常工作了,但我注意到不同的服务器管理器程序的行为不同

在保存配置文件时,FileSystemWatcher会拾取两个“更改”事件。这会导致我的程序将配置文件FTP两次,而我只需要一次

在其他情况下,我看到它在保存配置文件时可能会创建4、5或6个“更改”事件

当这些文件实际上只保存一次时,处理这些文件的最佳方式是什么

我真的不想设置一些东西来轮询目录中的文件更改…就像每次保存配置时,我都会得到一个副本以及附加到别处复制的文件名的日期/时间戳一样

我在谷歌上看到了很多建议,甚至在Stackoverflow上也看到了,但对我来说,似乎没有什么是综合性的

如果队列中不存在“更改”事件,我想我可以将文件名放入队列中。不确定这是否是最佳近似值

以下是我的示例代码:

启动代码:

private DateTime _lastTimeFileWatcherEventRaised = DateTime.Now;

_watcherCFGFiles = new FileSystemWatcher();
_watcherCFGFiles.Path = @"C:\ACME";
_watcherCFGFiles.IncludeSubdirectories = true;
_watcherCFGFiles.Filter = "*ServerConfig.cfg";

_watcherCFGFiles.NotifyFilter = NotifyFilters.Size;
//_watcherCFGFiles.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.FileName;

_watcherCFGFiles.Changed += new FileSystemEventHandler(LogFileSystemChanges);
_watcherCFGFiles.Created += new FileSystemEventHandler(LogFileSystemChanges);
_watcherCFGFiles.Deleted += new FileSystemEventHandler(LogFileSystemChanges);
_watcherCFGFiles.Renamed += new RenamedEventHandler(LogFileSystemRenaming);
_watcherCFGFiles.Error += new ErrorEventHandler(LogBufferError);
_watcherCFGFiles.EnableRaisingEvents = true;  
这是“更改”事件的实际处理程序。如果第二个“更改”事件在700毫秒内,我将跳过第一个“更改”事件。但这并不能解释生成3-4个更改事件的文件

    void LogFileSystemChanges(object sender, FileSystemEventArgs e)
    {
        string log = string.Format("{0} | {1}", e.FullPath, e.ChangeType);

        if( e.ChangeType == WatcherChangeTypes.Changed ) 
        { 
            if(DateTime.Now.Subtract(_lastTimeFileWatcherEventRaised).TotalMilliseconds < 700) 
            { 
                return; 
            }  

           _lastTimeFileWatcherEventRaised = DateTime.Now;

           LogEvent(log);

           // Process file
           FTPConfigFileUpdate(e.FullPath);   
       }
     }
void LogFileSystemChanges(对象发送方、FileSystemEventArgs e)
{
string log=string.Format(“{0}{1}”,e.FullPath,e.ChangeType);
if(e.ChangeType==WatcherChangeTypes.Changed)
{ 
if(DateTime.Now.Subtract(_lastTimeFileWatcherEntraised).totalMillimes<700)
{ 
返回;
}  
_LastTimeFileWatcherEntraised=DateTime.Now;
日志事件(log);
//进程文件
FTPConfigFileUpdate(例如FullPath);
}
}

这是正常的行为,因为当文件更改内容时,防病毒系统或其他程序会进行更多写入。我通常创建一个(全局)然后检查文件名是否存在,如果不存在,则将文件名放入其中,并在3-5秒后启动异步操作以删除文件名。

这是预期的行为-因此您需要了解在特定情况下如何处理它


文件系统没有“程序完成此文件的工作”的概念。也就是说,可以编写更新的编辑器(打开/写入/关闭)每次击键时,文件系统都会报告很多更新,但从用户的角度来看,当编辑器关闭时,只有一个更新。

我也有同样的问题。我使用了一个哈希映射,将文件名映射到写入时间,然后将其用作文件的查找表,以检查是否应用了更改的事件很快。我定义了一些epsilon(对我来说,大约需要2秒来确保事件被刷新)。如果在映射中找到的时间早于此,我会将其放在一个队列中进行处理。基本上,我所要做的就是使HashMap与事件和更改保持最新,这就解决了(尽管您可能希望根据应用程序更改epsilon值)。

它没有防病毒功能。在某些情况下,配置程序似乎多次保存文件。每次按下“确定”后更新表中的条目时,都会自动保存一个特定程序“。哈希表的想法似乎很有趣……由于每个配置文件都是唯一的,我想我可以将键设置为文件名和值e.FullPath?也许可以使用System.Timer每隔10-15分钟检查一次哈希表?我想知道以前是否有人使用过这种技术和/或是否有示例代码。。。。