0

I'm using the file watcher class in C# and anytime a file is created/modified I want to write that change to a log file. Should I have the StreamWriter open and write to the file upon each notification? Or should the StreamWriter be a member variable that is left open until the program is closed? The program does nothing else but watch a specific subdirectory and log changes.

   using System;
    using System.IO;
    using System.Security.Permissions;
    
    public class Watcher
    {
       private static string path;
        public static void Main()
        {
            Run();
        }
    
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        private static void Run()
        {
            //gets input from user for assigns it to path
    
            // Create a new FileSystemWatcher and set its properties.
            using (FileSystemWatcher watcher = new FileSystemWatcher())
            {
              using (StreamWriter outputFile = File.AppendText(path))
              {//write to file with time stamp indicating file watch 
               //start time
              }
                watcher.Path = path;
    
                // Watch for changes in LastAccess and LastWrite times, and
                // the renaming of files or directories.
                watcher.NotifyFilter = NotifyFilters.LastAccess
                                     | NotifyFilters.LastWrite
                                     | NotifyFilters.FileName
                                     | NotifyFilters.DirectoryName;
    
                // Only watch text files.
                watcher.Filter = "*.txt";
    
                // Add event handlers.
                watcher.Changed += OnChanged;
                watcher.Created += OnChanged;
                watcher.Deleted += OnChanged;
                watcher.Renamed += OnRenamed;
    
                // Begin watching.
                watcher.EnableRaisingEvents = true;
    
                // Wait for the user to quit the program.
                Console.WriteLine("Press 'q' to quit the sample.");
                while (Console.Read() != 'q') ;
            }
        }
    
        // Define the event handlers.
        private static void OnChanged(object source, FileSystemEventArgs e){
            using (StreamWriter outputFile = File.AppendText(path))
              {//write to file with time stamp indicating what changed
              }
            // Specify what is done when a file is changed, created, or deleted.
            Console.WriteLine($"File: {e.FullPath} {e.ChangeType}");
}

    private static void OnRenamed(object source, RenamedEventArgs e){
                 using (StreamWriter outputFile = File.AppendText(path))
                  {//write to file with time stamp indicating what renamed
                  }
                // Specify what is done when a file is renamed.
                Console.WriteLine($"File: {e.OldFullPath} renamed to {e.FullPath}");
        }
   
}
user13985180
  • 151
  • 1
  • 1
  • 9
  • 1
    I would use `File.AppendAllText()` and let .NET and the OS do the work. If you keep it open the entire time, what happens if the app crashes? Another option is to use an existing logging API and let it do the heavy lifting. – 001 Oct 23 '20 at 18:32
  • 1
    Both. Since the FileSystemWatcher often generates MULTIPLE events in rapid succession, opening and then immediately closing it might actually cause problems with file access. You could use some kind of TIMER that closes the file after XX seconds of inactivity. You'd move the StreamWriter out to class level like you mentioned so you can see if it needs to be closed and/or opened. – Idle_Mind Oct 23 '20 at 18:34
  • The question is: Do you really need that little bit extra performance (if even exists) that keeping the file handle open could give you? – Steve Oct 23 '20 at 18:34
  • At best, your question is opinion based. But even that has been addressed many times, and by far the prevailing opinion is to dispose your object as soon as you no longer need it. See duplicate. – Peter Duniho Oct 23 '20 at 18:38
  • 1
    In my opinion this question was closed with a little too much haste. The duplicate indicated (very little authoritative) does not address the context presented by the OP. The FileSystemWatcher is an ugly beast to handle. Of course we all agree on the general rule. If it implements Disposable then you need to call Dispose as soon as possible, but perhaps here we have a situation that requires more arguments – Steve Oct 23 '20 at 18:46
  • What is the difference between File.AppendAllText() and using the StreamWriter with the "using" statement? Are they not esentially doing the same thing? I'm new to C# – user13985180 Oct 23 '20 at 19:00
  • If nothing else ever needs to write to this file then it's no harm to keep the handle open (since by doing that with write access you prevent other processes to make writes). – Evk Oct 23 '20 at 19:09

0 Answers0