File watcher best way or other way - Check file, event, if something changed

Markus Freitag 3,791 Reputation points
2022-09-03T18:33:14.23+00:00

Hello,

<CHANGED>  
 <VARIANTS  takeIt="C:\Root\XMLBase\Test.xml" changed="speed value from 34 to 79" />  
</CHANGED>  

I need to check a folder for changes to files cyclically.
Filename is Changed.XML

What is the best way to do this?
Via FileWatcher from Microsoft? I think I can use the sample from Microsoft, without static inside my project.
Via a timer?
Via a thread or task?

Can you show me the alternatives?
Which variant do you prefer?

I need to check if the file has changed.
If changed, I need to read and visualize the attributes takeIt and changed.

Sample

<CHANGED>  
 <VARIANTS  takeIt="C:\Root\XMLBase\Test03.xml" changed="power value from 22 to 66" />  
</CHANGED>  
  
<CHANGED>  
 <VARIANTS  takeIt="C:\Root\XMLBase\Test02.xml" changed="Frequence value from 22.022 to 56.323" />  
</CHANGED>  

Or I cyclically check the file to see if it has changed.
Whether the element / attribute takteIt="C:\Root\XMLBase\Test02.xml" name has changed.

I think that is the best.
The FileWatcher calls the OnChanged event more often, however.
Timer, Task, or FileWatcher, which is better?

Developer technologies | C#
{count} votes

Accepted answer
  1. Jack J Jun 25,296 Reputation points
    2022-09-06T09:33:37.437+00:00

    @Markus Freitag , Welcome to Microsoft Q&A, you could refer to the following steps to detect if the file changes and get the changed text.

    First, Please create the duplicate of your files.

    Second, Please use FileSystemWatcher to detect if the file has been changed.

    Third, you could use DiffMatchPatch API(install nugetpackage DiffMatchPatch) to get the difference between two files.

    Finally, Please reset the duplicate of the file.

    Code example:

     static string path = "E:\\Test";  
            static void Main(string[] args)  
            {  
                  
      
                foreach (var item in Directory.GetFiles(path))  
                {  
                    Console.WriteLine(item);  
                    string path = item.Replace(Path.GetFileNameWithoutExtension(item), Path.GetFileNameWithoutExtension(item) + "copy");  
                    if(!File.Exists(path))  
                    {  
                        File.Copy(item, item.Replace(Path.GetFileNameWithoutExtension(item), Path.GetFileNameWithoutExtension(item) + "copy"));  
                    }  
                     
                }  
                var watcher = new FileSystemWatcher(path);  
      
                watcher.NotifyFilter = NotifyFilters.Attributes  
                                     | NotifyFilters.CreationTime  
                                     | NotifyFilters.DirectoryName  
                                     | NotifyFilters.FileName  
                                     | NotifyFilters.LastAccess  
                                     | NotifyFilters.LastWrite  
                                     | NotifyFilters.Security  
                                     | NotifyFilters.Size;  
      
                watcher.Changed += OnChanged;  
      
      
                watcher.Filter = "*.xml";  
                watcher.IncludeSubdirectories = true;  
                watcher.EnableRaisingEvents = true;  
                Console.ReadKey();  
                  
            }  
      
            private static void OnChanged(object sender, FileSystemEventArgs e)  
            {  
                if (e.ChangeType == WatcherChangeTypes.Changed)  
                {  
                    Console.WriteLine($"Changed: {e.FullPath}");  
                    string path1 = e.FullPath.Replace(Path.GetFileNameWithoutExtension(e.FullPath), Path.GetFileNameWithoutExtension(e.FullPath)+"copy");  
                    var ori = File.ReadAllText(path1);  
                    var current = File.ReadAllText(e.FullPath);  
                    diff_match_patch dmp = new diff_match_patch();  
                    List<Diff> diff = dmp.diff_main(ori, current);  
                    dmp.diff_cleanupSemantic(diff);  
                    for (int i = 0; i < diff.Count; i++)  
                    {  
                        if (diff[i].operation.ToString()=="DELETE")  
                        {  
                            Console.WriteLine(diff[i].text+"has changed to"+ diff[i+1].text);  
                        }  
                    }  
                    File.Delete(path1);  
                    File.Copy(e.FullPath, path1);  
                }  
                 
            }  
    

    Based on my test, it works well.

    238163-image.png

    Best Regards,

    Jack


    If the answer is the right solution, please click "Accept Answer" and upvote it.If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.