Detecting File Changes with FileSystemWatcher
If you are developing a Windows Explorer-style application or integrating with a legacy or third-party system that can only provide information via files, you may need to monitor the files within a folder. The FileSystemWatcher class permits this.
The FileSystemWatcher class is found in the System.IO namespace. This is an interesting class that provides all of the functionality required to monitor a directory on a disk and identify when its contents change. It achieves this by linking directly to the file system notifications provided by the Windows operating system and raising events when items change.
The FileSystemWatcher class provides four events that are raised to indicate a change to a file or folder. The four events and the activities that they signify are:
- Changed. Raised when a file or a folder is modified.
- Created. Raised when a new file or folder is created.
- Deleted. Raised when an existing file or folder is deleted.
- Renamed. Raised when an existing file or folder is renamed.
Creating the File System Monitor Project
In this article we will create a new Windows Forms project to demonstrate the use of the FileSystemWatcher class. This will be a simple application that monitors a folder for file changes. Whenever a change is made, it will be logged to a list box within the application's main form.
To begin, create a new Windows Forms project named "FileSystemMonitor".
Creating the File Monitor Form
Rename the automatically generated form to "FileMonitorForm" and add the following controls. You may wish to organise these controls into groups in the form and add descriptive labels. After designing your form, it should look similar to the image beneath the table.
|Control Name||Type||Special Properties||Purpose|
|FolderInput||TextBox||Text = "c:\Demo"||Allows the user to input the path to the folder that they wish to monitor for changes.|
|ChangeLogList||ListBox||Logs all of the events that have occurred when a file or folder has been created, modified, deleted or renamed.|
|MonitoringInput||CheckBox||Checked = False|
Text = "Monitoring Enabled"
|Enables and disables monitoring of the selected folder.|
|FileFilterInput||TextBox||Text = "*.*"||Permits filtering of the items that are monitored, based upon file and folder names.|
Adding the FileSystemWatcher
To permit monitoring of file changes we need a FileSystemWatcher object. The object will be configured by form events when the path to monitor and the filtering options are changed, and when monitoring is enabled and disabled. To allow this configuration, the object must have a variable scope that is visible to all of the form's methods. It will therefore be created within the class's code block.
FileSystemWatcher appears in the System.IO namespace so ensure that you have using System.IO; at the top of your form code before adding the following declaration to the FileMonitorForm class:
private FileSystemWatcher _watcher;
Preventing Cross-Thread Operations
By default, when the FileSystemWatcher object raises notification events, the delegate calls are made on a thread from the system thread pool. This will generally not be the same thread as that being used to control the form. As the demonstration application will require that the file changes be logged within a visual element of the form, using the allocated thread to modify the list box contents would result in a cross-threading operation and an IllegalOperationException being thrown.
To force the FileSystemWatcher to use the thread that the form is operating under and to avoid errors, the SynchronizingObject property can be used. This property will be set to the form's class so that the form object is used to marshal the event handler calls. To set this property, modify the form's constructor as follows:
_watcher = new FileSystemWatcher();
_watcher.SynchronizingObject = this;
22 March 2008