6 Tips for Coaching Your Development Team3 Handy Icon Functions You Can Use

Introduction To FileSystemWatcher

October 1st, 2007

Introduction To FileSystemWatcherA common behind-the-scenes operation is to watch for the arrival of new files in a folder. I’ve had several projects where I had to watch for files arriving via FTP or HTTP uploads and then move these files off the web server and process them elsewhere on the network. In this article, we’ll look at the basics of using the FileSystemWatcher class to monitor file activity.

Creating a FileSystemWatcher

FileSystemWatcher is a member of the System.IO namespace. Remember that you’ll either need to import this namespace or explicitly type it out to use this class. When you create a FileSystemWatcher object you can create it with no parameters, you can specify the path you want it to monitor or you can specify both the path and the filter you wish to use. Here are some examples:

Watcher = New FileSystemWatcher
'.
'.....
'.
Watcher = New FileSystemWatcher(WatchPath)
'.
'.....
'.
Watcher = New FileSystemWatcher(WatchPath, WatchFilter)

The path parameter/property can be any valid UNC file path so you can watch both local and networked drives. Make sure that your user has access right to any paths they will need to access. This is especially critical for Windows Service applications running under LOCAL SERVICE or NETWORK SERVICE built-in IDs. Remember these IDs will usually need to be give access to target folders by an administrator.

The filter parameter/property is used to determine which files will be watched. You can use standard wildcards to look for particular file types, for example “*.doc”, or for a specific file, for example “annual_report.xls”.

The NotifyFilter

There are two filter properties in the FileSystemWatcher, one, as we mentioned above, to determine the file name(s) to watch for and NotifyFilter which says what kind of file system events to watch. By default, the NotifyFilter property is set to watch for a file to be written or for the file or directory name to be changed. You can also check for the file size, file security, or attributes changing. This property is a bitwise mask so you’ll set it by using Or, like so:

 
'.
'.
Watcher.NotifyFilter = (NotifyFilters.LastAccess Or NotifyFilters.LastWrite Or NotifyFilters.FileName Or NotifyFilters.DirectoryName)
'.
'.

Asynchronous Watching

In some cases, you will want to have your application continue running while files arrive. I’ve found this to be the most common scenario. To do this, you’ll setup the information mentioned above, then you’ll want to add event handlers for each type of event you wish to capture. These are Changed, Created, Deleted, and Renamed. You can either declared the FileSystemWatcher as WithEvents or you can use AddHandler. WithEvents is handy for having Visual Studio provide the code snippets but is less flexible than using AddHandler. You will need to create the event handler routines for the events you want to handle.

Now that everything is ready, we can begin watching. To do this, we set the EnableRaisingEvents property to True. We can use this property to turn watching on and off.

Here’s our complete code:

Private Watcher As FileSystemWatcher

'
' Other class code here
'

Private Sub StartWatcher(ByVal WatchPath As String, ByVal WatchFilter As String)
    Watcher = New FileSystemWatcher(WatchPath, WatchFilter)
    Watcher.NotifyFilter = (NotifyFilters.LastAccess Or NotifyFilters.LastWrite Or NotifyFilters.FileName Or NotifyFilters.DirectoryName)
    AddHandler Watcher.Created, AddressOf OnCreated
    AddHandler Watcher.Changed, AddressOf OnModified
    AddHandler Watcher.Deleted, AddressOf OnModified
    AddHandler Watcher.Renamed, AddressOf OnRenamed
    Watcher.EnableRaisingEvents = True
End Sub

Private Sub OnCreated(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs)
    'Code for newly created files here
    If e.Name = "error.txt" Then
        'error file found, do something about it
    Else
        'processing as normal
    End If
End Sub

Private Sub OnModified(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs)
    'Code for changed or deleted files here
End Sub

Private Sub OnRenamed(ByVal sender As Object, ByVal e As System.IO.RenamedEventArgs)
    'Code for renamed file here
    If e.OldName.Contains("error") Then
        're-processing an error file
    Else
        'normal processing
    End If
End Sub

When a file meeting our criteria arrives or is changed in our target folder, the events will fire. We can use the ‘e’ parameter to determine the exact nature of the event and to get the file information as seen in the code for OnCreated and OnRenamed above. Note that the event arguments parameter is different for the Renamed event. It returns information about the new file and the old file.

Synchronous Watching

Sometimes you may want to wait for the arrival of a particular file before allowing your code to continue. You can use the FileSystemWatcher for this as well by using the WaitForChanged method. To use this method you will need to setup the FileSystemWatcher object as before with the path and filters. However, you will not need to add event handlers, but, if they are defined, they will be fired even if EnableRaisingEvents property is set to false.

There are two overloads for the WaitForChanged method. The first overload has a single parameter that indicates the type of event to be watched for, such as created or renamed. The second overload adds the timeout value in milleseconds. I would recommend not using the first since it will wait indefinitely for the event to occur.

Here is an example of using this method:

Dim Results As WaitForChangedResult = Watcher.WaitForChanged(WatcherChangeTypes.Created, 10000)
If Results.TimedOut Then
    'Operation timed out code
Else
    'regular processing code
End If

Working With Multiple Folders and File Types

Often you’ll have requirements to monitor several different folders. Depending upon your needs, there are a few different ways to handle this.

First, if you’re just monitoring a folder and its subdirectories, you can set the IncludeSubdirectories property to True. This will allow you to add in anything under your main target folder automatically.

What if you need to monitor multiple folders or multiple file types? Unfortunately, each FileSystemWatcher can only monitor one folder structure and one file type. In this case, we will want to create multiple instances of the object to handle each folder and file type combo. Remember though that each of these instances can use the same event handlers.

Tips and Tricks

You can use the InternalBufferSize property to increase the size of the memory buffer for this operation. This can help prevent missing file events in very active systems. However, it can impose memory and performance penalties so be careful about using it.

Keep the size of your event code small. This helps insure better performance and prevents lost events. You may want to consider using threading if the processing required for each file event is considerable.

If a folder is cut and pasted this is considered a rename operation, not a create operation. This has been known to be confusing to some people, particularly when they’re using this method to test their code.

File actions may raise multiple events so you will need to take precautions against processing the same file multiple times.

That’s all for this introduction to the FileSystemWatcher object. Let me know if you have any questions or further observations about this object by leaving me a comment.

Share This Article: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • DotNetKicks
  • DZone

Entry Filed under: VB.NET Tutorials


Rate This Article:

Not That GoodCould Be BetterOKGoodGreat (6 votes, average: 5 out of 5)
Loading ... Loading ...

11 Comments Add your own

  • 1. J-Micharl  |  November 18th, 2007 at 12:37 pm

    Hello ;) Little question for you.

    Is there a way to dispose a FSW in a for each?
    Example:
    dim n as control
    for each n in controls
    if typeof(n) is filesystemwatcher then
    if path = “path to delete” then n.dipose()
    end if
    next

    When I try this code, I have an error :
    It tells me that N (system.windows.forms.control) will never be the type of FileSystemWatcher.

    Is there another method? :)
    Thx

  • 2. Bill  |  November 28th, 2007 at 1:46 pm

    “File actions may raise multiple events so you will need to take precautions against processing the same file multiple times.”

    Yes. Yes. Yes. ….but how?

  • 3. jfrankcarr  |  November 28th, 2007 at 3:18 pm

    J-Micharl,

    The way I do this is to not use the controls collection at all. Instead I use a generic List of FileWatchers that I can create and remove as needed.

  • 4. jfrankcarr  |  November 28th, 2007 at 3:22 pm

    Bill,

    The way I’m doing this is to put a file on a generic Queue if it isn’t already on the queue. Here’s an example:

     Private Sub OnCreated(ByVal source As Object, ByVal e As FileSystemEventArgs)
            If Not WorkQueue.Contains(e.FullPath) Then
                WorkQueue.Enqueue(e.FullPath)
            End If
    End Sub
  • 5. Jn-Michael  |  March 10th, 2008 at 3:08 pm

    Is there a way I could have a little example about using WorkQueue or Generic List, just to put me on the track ^^

  • 6. shahaji  |  March 20th, 2008 at 2:38 am

    If the system file like ntldr or some files from temp foder that always change at that time can we avoid that perticular file or folder.have u solution for this

  • 7. Vikram  |  June 11th, 2008 at 12:19 am

    Is there anyway we can have two type of files being watched by a FSW e.g abc*.* and *.def

  • 8. Tamilarasi  |  July 7th, 2008 at 1:12 am

    the article is very much useful. i am having one big question that
    “Can we watch a folder available in FTP ? “

  • 9. kirti  |  July 24th, 2009 at 1:17 am

    how to use with FTP for watch on ftp folder when file upload in any subfolder of given folder it automatically download file so how we use with ftp

    Reply is highly valuable

    Regards

    Kirti Darji

  • 10. Elmer  |  September 29th, 2009 at 10:55 pm

    Is there a way to know who made the changes, deleted a file and created a new file?

    Thanks,

  • 11. Moises  |  February 24th, 2010 at 11:10 am

    Is posible see the new change in a text file if the component threw a OnModified event?

    For example:
    Before: test.txt (Hello world )

    After: test.txt (Hello world!!!!! )

    I need detect this change (!!!!!)

    thanks,

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Visit Me At My New Site, Programming In C#

Most Popular Articles

Highest Rated Articles

Categories

Most Recent Articles

Feeds

 Subscribe in a reader

To subscribe by e-mail
Enter your address here

Delivered by FeedBurner

VB Opportunities

Archives