Monitoring the File System for Changes

Files and Directories, Windows Forms

In this article I am going to show you how to monitor a folder for changes. A reason why you might want to do this is for example if you want to keep two files in different locations in sync. When the original file is changed it would trigger an event and you can update the copy in the other location with the updated original file.

The .NET framework provides a component called the FileSystemWatcher which is designed to do exactly what its name suggests – watch the file system for changes. Let’s create an example which uses this component.

Create a new Windows Forms Application project and design a form which looks similar to the one below:

Then add a FileSystemWatcher component to your form from the Components Toolbox in Visual Studio.

Next we’ll configure the FileSystemWatcher and start monitoring a folder in the Monitor button’s event handler. The code for this is shown below:

private void btnMonitor_Click(object sender, EventArgs e)
{
    try
    {
        // Watch for changes on this path
        fileSystemWatcher.Path = txtPath.Text.Trim();
        
        // Watch for changes on all files
        fileSystemWatcher.Filter = "*.*";

        // Also watch for changes within sub directories
        fileSystemWatcher.IncludeSubdirectories = true;

        // Begin watching
        fileSystemWatcher.EnableRaisingEvents = true;
    }
    catch (Exception ex)
    {
        MessageBox.Show("An error occurred: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

As you can see the code is quite self explanatory. We are starting the FileSystemWatcher by setting its EnableRaisingEvents property to true.

Next we must subscribe to its four events – the Changed, Created, Deleted, and Renamed events.

private void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
{
    txtStatus.Text = string.Format("{0} {1} changed. {2}", 
                                   txtStatus.Text, 
                                   e.FullPath, 
                                   Environment.NewLine);
}

private void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
    txtStatus.Text = string.Format("{0} {1} created. {2}", 
                                   txtStatus.Text, 
                                   e.FullPath, 
                                   Environment.NewLine);
}

private void fileSystemWatcher_Deleted(object sender, FileSystemEventArgs e)
{
    txtStatus.Text = string.Format("{0} {1} deleted. {2}", 
                                   txtStatus.Text, 
                                   e.FullPath, 
                                   Environment.NewLine);
}

private void fileSystemWatcher_Renamed(object sender, RenamedEventArgs e)
{
    txtStatus.Text = string.Format("{0} {1} renamed. {2}", 
                                   txtStatus.Text, 
                                   e.FullPath, 
                                   Environment.NewLine);
}

When each of the above events fires, we are updating the main textbox (txtStatus) with some text which describes the event. A screenshot of this can be seen below:

As you can see from the screenshot above, whenever a file is added the FileSystemWatcher is firing a change event for the folder and two more for the file. If many files are added to that directory at once our application could easily be swamped by an unceasing series of events. That’s where the NotifyFilter property comes in.

The NotifyFilter property allows you indicate which type of changes you want to monitor. It can be set using any combination of the following values from the NotifyFilters enumeration:

public enum NotifyFilters
{
    // The name of the file.
    FileName = 1,
    // The name of the directory.
    DirectoryName = 2,
    // The attributes of the file or folder.
    Attributes = 4,
    // The size of the file or folder.
    Size = 8,
    // The date the file or folder last had anything written to it.
    LastWrite = 16,
    // The date the file or folder was last opened.
    LastAccess = 32,
    // The time the file or folder was created.
    CreationTime = 64,
    // The security settings of the file or folder.
    Security = 256,
}

You can combine these values using bitwise arithmetic as shown below:

fileSystemWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size;

This line of code is telling the FileSystemWatcher to only watch for changes to file names and file sizes. If one of these changes occurs the fileSystemWatcher_Changed event will fire. If, for example, a change to a file attribute occurs, such as a file is set to read-only, the change event will not fire. For it to fire we must add NotifyFilters.Attributes to the NotifyFilter values.

Now you should have a clear understanding of how to monitor the file system for changes using the .NET FileSystemWatcher component.

If you liked this article you can subscribe to my full RSS feed here. Please feel free to leave any questions or comments below.

Dave

1 comment… add one
  • Srini Link Reply

    Nice article,

    if we want to monitor file copy and open events also, then how can we achieve it.

    could you please help in this?
    thanks in advance

Leave a Comment