131

Is there some mechanism by which I can be notified (in C#) when a file is modified on the disc?

Mihai Limbășan
  • 64,368
  • 4
  • 48
  • 59
PaulB
  • 23,264
  • 14
  • 56
  • 75
  • 2
    See this [answer](http://stackoverflow.com/questions/381976/handling-multiple-change-events-in-filesystemwatcher/382996#382996) for more information on the FileSystemWatcher class and the events it raises. – ChrisF Apr 21 '12 at 13:02

3 Answers3

240

You can use the FileSystemWatcher class.

public void CreateFileWatcher(string path)
{
    // Create a new FileSystemWatcher and set its properties.
    FileSystemWatcher watcher = new FileSystemWatcher();
    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 += new FileSystemEventHandler(OnChanged);
    watcher.Created += new FileSystemEventHandler(OnChanged);
    watcher.Deleted += new FileSystemEventHandler(OnChanged);
    watcher.Renamed += new RenamedEventHandler(OnRenamed);

    // Begin watching.
    watcher.EnableRaisingEvents = true;
}

// Define the event handlers.
private static void OnChanged(object source, FileSystemEventArgs e)
{
    // 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)
{
    // Specify what is done when a file is renamed.
    Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
}
Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
  • 14
    Thanks for the nice example. I'll also point out that you can use the method WaitForChanged on FileSystemWatcher if you are looking for a blocking (synchronous) way to watch for changes. – Mark Meuer Sep 20 '13 at 17:38
  • 23
    Thanks for this example. The MSDN has pretty much the same [here](http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.filter%28v=vs.100%29.aspx). Also, some people might want to watch a whole directory tree - use `watcher.IncludeSubdirectories = true;` to achieve that. – Oliver Nov 14 '13 at 22:59
  • 1
    `OnChange` fires without actual change (_e.g: hitting `ctrl+s` without any actual change_), is there any way to detect fake changes? – Mehdi Dehghani Oct 26 '19 at 09:14
  • 1
    @MehdiDehghani: Not that I know of, the only way seems to be to actually keep a snapshot of the file and compare that byte-wise to the current (presumably changed) version. The `FileSystemWatcher` only is able to detect events at the file system level (i.e. if the OS triggers an event). In your case Ctrl+S triggers such an event (whether that happens or not depends on the actual application though). – Dirk Vollmar Oct 26 '19 at 09:16
  • Is FileSystemWatcher cross-platform ? – Vinigas Apr 16 '20 at 15:15
  • Doesn't work in my case. I've got Valve's Steam changing appmanifest_appid.acf in the steamapps folder, and I'd like to get notified when the application updates. The file updates when the game starts to update, notepad++ detects the change and prompts to reload the file. But the `FileSystemWatcher` doesn't detect these changes. I coded it correctly, because I do get notified when I edit the manifest file in the notepad++ and press Ctrl+S. – KulaGGin Jun 21 '22 at 20:48
75

That would be System.IO.FileSystemWatcher.

Mihai Limbășan
  • 64,368
  • 4
  • 48
  • 59
  • The doc said using System.IO only https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=net-7.0 – Ray Chakrit Dec 31 '22 at 13:40
7

Use the FileSystemWatcher. You can filter for modification events only.

Majid
  • 13,853
  • 15
  • 77
  • 113
Shea
  • 11,085
  • 2
  • 19
  • 21