Recipe 14.10. Watching for File and Directory Changes


Problem

You need to monitor a directory, watching for any files that are added, removed, or changed.

Solution

Sample code folder: Chapter 14\FileWatcher

Use a FileSystemWatcher object and its events notify you of any changes in a specific directory or to specific files. System.IO.FileSystemWatcher includes many properties that let you adjust the types of files or changes to monitor. It also includes distinct events for most types of changes.

Discussion

The code in this recipe implements a simple test program that watches for any change in a selected directory. Create a new Windows Forms application, and add the following controls to Form1:

  • A TextBox control named WatchDirectory.

  • A TextBox control named WatchFilter.

  • A CheckBox control named IncludeSubdirectories. Change its Text property to Include Subdirectories.

  • A CheckedListBox control named WatchFor.

  • A Button control named StartStop. Change its Text property to Start.

  • A ListBox control named DirectoryEvents.

Add additional labels, if desired, and arrange the form to look like the one in Figure 14-7.

Open the source-code file for the form, and add the following code to the Form1 class template:

 Public WithEvents WatchForChanges As IO.FileSystemWatcher Private Sub Form1_Load(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles MyBase.Load    ' ----- Add the types of actions. The Enum class's    '       GetNames method returns a collection of the    '       enumeration type's members as strings. Since    '       "Enum" is a keyword in Visual Basic, the    '       "Enum" class must be escaped with brackets.    For Each scanFilters As String In [Enum].GetNames( _          GetType(IO.NotifyFilters))       WatchFor.Items.Add(scanFilters) 

Figure 14-7. Controls for the directory watcher sample


    Next scanFilters End Sub Private Sub StartStop_Click(ByVal sender As System.  Object, _       ByVal e As System.EventArgs) Handles StartStop.Click    ' ----- Start or stop watching a directory.    Dim monitorEvents As Integer = 0    If (StartStop.Text = "Start") Then       ' ----- Check for valid settings.       If (My.Computer.FileSystem.DirectoryExists( _             WatchDirectory.Text) = False) Then          MsgBox("Please specify a valid directory.")          Exit Sub       End If       If (WatchFor.SelectedItems.Count = 0) Then          MsgBox("Please specify the events to watch for.")          Exit Sub       End If       ' ----- Build the events setting. The Enum class's       '       Parse( ) method converts a string back to its       '       Integer enumeration value, in this case,       '       from the IO.NotifyFilters enumeration.         For Each scanEvents As String In WatchFor.CheckedItems          monitorEvents = monitorEvents Or _             CInt([Enum].Parse(GetType(IO.NotifyFilters), _             scanEvents))       Next scanEvents       ' ----- Start the watching process.       DirectoryEvents.Items.Clear( )       WatchForChanges = New IO.  FileSystemWatcher       WatchForChanges.SynchronizingObject = Me       WatchForChanges.Path = WatchDirectory.Text       WatchForChanges.Filter = WatchFilter.Text       WatchForChanges.NotifyFilter = monitorEvents       WatchForChanges.IncludeSubdirectories = IncludeSubdirectories.Checked       WatchForChanges.EnableRaisingEvents = True       StartStop.Text = "Stop"    Else       ' ----- End the watching process.       WatchForChanges.EnableRaisingEvents = False       WatchForChanges.Dispose( )       WatchForChanges = Nothing       StartStop.Text = "Start"    End If End Sub Private Sub WatchForChanges_Changed(ByVal sender As Object, _       ByVal e As System.IO.  FileSystemEventArgs) _       Handles WatchForChanges.Changed    DirectoryEvents.Items.Add("Changed: " & e.Name) End Sub Private Sub WatchForChanges_Created(ByVal sender As Object, _       ByVal e As System.IO.FileSystemEventArgs) _       Handles WatchForChanges.Created    DirectoryEvents.Items.Add("Created: " & e.Name) End Sub Private Sub WatchForChanges_Deleted(ByVal sender As Object, _       ByVal e As System.IO.FileSystemEventArgs) _       Handles WatchForChanges.Deleted    DirectoryEvents.Items.Add("Deleted: " & e.Name) End Sub Private Sub WatchForChanges_Renamed(ByVal sender As Object, _       ByVal e As System.IO.RenamedEventArgs) _       Handles WatchForChanges.Renamed    DirectoryEvents.Items.Add("Renamed: " & e.OldName & _       " to " & e.Name) End Sub 

To use the program, enter a valid directory in the WatchDirectory field, optionally enter a filename or wildcard in the WatchFilter field, and select one or more entries in the WatchFor list. Now click the StartStop button, and begin making changes in the target directory.

The FileSystemWatcher class monitors activity in a specific directory and raises events based on changes in that directory. The class often reports any change immediately. This means that if you create a new file in the directory and take several minutes to fill it with data before closing it, FileSystemWatcher will report the creation of the file at the start of its life, not when it was closed. This can lead to interaction issues in your program. When you receive notification of a new file in a monitored directory, you should confirm that the complete file has been written out before processing it.

The FileSystemWatcher class uses a shared memory buffer for part of its processing. This buffer is limited in size, so if you experience a lot of changes in a directory, the buffer may "overflow, " and you will lose notifications. The object includes an Error event that will let you know when this happens. Also, you can adjust the InternalBufferSize property to allocate more buffer space.

The Toolbox displayed for a Windows Forms form in Visual Studio includes a FileSystemWatcher control. This control is the same as the class included in this recipe's sample code. If you choose to declare the object through code instead of as a control, make sure you set its SynchronizingObject property to the active form (as is done in the sample code) to prevent intrathread errors.




Visual Basic 2005 Cookbook(c) Solutions for VB 2005 Programmers
Visual Basic 2005 Cookbook: Solutions for VB 2005 Programmers (Cookbooks (OReilly))
ISBN: 0596101775
EAN: 2147483647
Year: 2006
Pages: 400

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net