Comparing 2 text files while actively looking for changes

47 Views Asked by At

I need my program to compare a main file with a reference file which is just a copy of the original one. The program actively looks for changes to the main file by comparing it to the comparison file to find discrepancy.

I need new blank lines to be ignored log wise (no log) but the shift to be taken account of so that if line 3 gets shifted to line 5, a change on line 5 happens it compares to the comparison file line 3 just as if it was not shifted.

This should be vice versa if lines were removed.

When setting up the program I have it set up to take the given directory, copy all .bas files into a folder in the applications root folder and id them.

After the setup is done I have FileSystemWatcher looking for changes to the main files and calling a comparison method for a file and its comparison file when a change is detected (this is not giving me problems but I am adding it for context)

static void Run()
        {
            try
            {
                // Iterate over the paths
                foreach (var kvp in paths)
                {
                    int id = kvp.Key;
                    string path = kvp.Value;

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

                    // Set the path and filter of the watcher
                    watcher.Path = Path.GetDirectoryName(path);
                    watcher.Filter = Path.GetFileName(path);

                    // Add event handlers for the Changed and Renamed events
                    watcher.Changed += OnChanged; 
                    watcher.Renamed += OnRenamed; 

                    // Enable the raising of events
                    watcher.EnableRaisingEvents = true;

                    // Write a debug message
                    Debug.WriteLine($"Running Reader for file {id}");

                    // Add the FileSystemWatcher to the list
                    watchers.Add(watcher);
                }

                // Wait until the task is cancelled
                cts.Token.WaitHandle.WaitOne();
            }
            catch (Exception ex)
            {
                // Write the exception message to the debug output
                Debug.WriteLine($"An error occurred: {ex.Message}");
            }
// This method is triggered when a file is renamed
        private static void OnRenamed(object source, RenamedEventArgs e)
        {
            // Call the OnChanged method to handle the event
            OnChanged(source, e);
        }
// Variable to store the last read time
        private static DateTime lastRead = DateTime.MinValue;

        // This method is triggered when a file is changed
        private static void OnChanged(object source, FileSystemEventArgs e)
        {
            // Compare the current and previous versions of the file and log any changes
            CompareAndLogChanges();
        }

My problem is with the comparison. So far, I approached the problem line by line, comparing the original file to the comparison file.

This works for changes withing lines but does not account for added and removed lines. No matter what I try I can't get it to take these changes into account.

private static void CompareAndLogChanges()
        {
            foreach (var kvp in paths)
            {
                int id = kvp.Key;
                string path = kvp.Value;
                string comparisonPath = comparisonPaths[id];
                bool fileRead = false;
                while (!fileRead)
                {
                    try
                    {
                        var comparisonLines = File.ReadLines(comparisonPath).ToList();
                        var currentLines = File.ReadLines(path).ToList();
                        if (!loggedLines.ContainsKey(id))
                        {
                            loggedLines[id] = new Dictionary<int, string>();
                        }
                        for (int i = 0; i < Math.Min(comparisonLines.Count, currentLines.Count); i++)
                        {
                            if (comparisonLines[i] != currentLines[i])
                            {
                                LogChange(id, i + 1, comparisonLines[i], currentLines[i]);
                            }
                            else if (loggedLines[id].ContainsKey(i + 1) && loggedLines[id][i + 1] != comparisonLines[i])
                            {
                                LogOriginalState(id, i + 1, comparisonLines[i]);
                            }
                        }
                        if (comparisonLines.Count != currentLines.Count)
                        {
                            if (comparisonLines.Count < currentLines.Count)
                            {
                                for (int i = comparisonLines.Count; i < currentLines.Count; i++)
                                {
                                    LogChange(id, i + 1, null, currentLines[i]);
                                }
                            }
                            else
                            {
                                for (int i = currentLines.Count; i < comparisonLines.Count; i++)
                                {
                                    LogChange(id, i + 1, comparisonLines[i], null);
                                }
                            }
                        }
                        fileRead = true;
                    }
                    catch (IOException)
                    {
                        Console.WriteLine($"File {id} is locked, retrying...");
                        System.Threading.Thread.Sleep(1000);
                    }
                }
            }
        }

This is the shell of the code for the comparison method. Any help or suggestions on how to compare while taking adding lines and removing lines in account would be huge and greatly appreciated.

I am willing to rebuild my whole comparison method and approach if there is a better way.

0

There are 0 best solutions below