Tech Corner: A look at the FileSystemWatcher class

Tags: Tech corner, FileSystemWatcher, software development, Nova

It's Tech Corner time!  In this blog, senior developer Chris Shallcross shares his experiences with the FileSystemWatcher class having finally needed to use it after 11 years....

When Microsoft released .Net 1.1 back in 2002 they included the FileSystemWatcher class.  Despite its eleven year history I only recently needed to use it.  To my surprise, it didn’t work out of the box.  There were quite a few gotchas that one needs to be aware of.

You won’t be told about everything

The watcher watches the contents of the watched folder, not the folder itself.  This means that the folder can be deleted or renamed without any notifications.

You can’t believe everything you are told

After a folder rename, subsequent file renames are reported on for the folder’s original name.

Try creating the file C:\One\File1.txt.  Then rename folder One to folder Two.  When you rename File1.txt to File2.txt you are told that File1.txt has been renamed to C:\One\File2.txt not C:\Two\File2.txt.

This happens because the watcher determines what directory to watch based on the handle, rather than the name of the directory. Renaming does not affect the handle.

If too much happens then the watcher loses track.

If changes do not occur at what Microsoft describes as a “manageable rate” then the watcher’s internal buffer can overflow.  An error event is thrown with an InternalBufferOverflowException so you know something has gone wrong.  However, at this point all is effectively lost.  All you can really do is scan your watched directories and rebuild your data store.

You can try to reduce the changes of an overflow by:

  • Increasing the InternalBufferSize.  However, this is expensive because it comes from non-paged memory that cannot be swapped out to disk.
  • You can use the NotifyFilter to filter out unwanted change notifications.
  • Or IncludeSubdirectories properties to reduce the number of files being watched.

These still will not stop an overflow.  It is more than likely that you will have to build in a rescan as a backup.

See Considerations for File Changes on High-Volume Systems

Locking

FileSystemWatcher is implemented with ReadDirectoryChangesW.  This function requires an active handle to a directory created with CreateFile.  The drawback to this is that the directory cannot be deleted or renamed while watching it.  At least in theory.  I can delete and rename the folder that I'm watching, I just cannot delete the parent folder of the folder that I'm watching.

You might get multiple events for the same action

And not only multiple events, but confusing ones.  I might expect a single Create event when I save a new file in Notepad but here is what I get:


File Created: C:\Watch\File1.txt
File Deleted: C:\Watch\File1.txt
File Created: C:\Watch\File1.txt
File Changed: C:\Watch\File1.txt
File Changed: C:\Watch\File1.txt

Saving a Word document is even more descriptive:

File Created: C:\Watch\Word.docx
File Deleted: C:\Watch\Word.docx
File Created: C:\Watch\Word.docx
File Created: C:\Watch\~WRD3651.tmp
File Changed: C:\Watch\~WRD3651.tmp
File Changed: C:\Watch\~WRD3651.tmp
File Changed: C:\Watch\~WRD3651.tmp
File Changed: C:\Watch\~WRD3651.tmp
File Changed: C:\Watch\~WRD3651.tmp
File: C:\Watch\Word.docx renamed to C:\Watch\~WRL3658.tmp
File: C:\Watch\~WRD3651.tmp renamed to C:\Watch\Word.docx
File Changed: C:\Watch\Word.docx
File Changed: C:\Watch\Word.docx
File Changed: C:\Watch\~WRL3658.tmp
File Created: C:\Watch\~$Word.docx
File Changed: C:\Watch\~$Word.docx
File Deleted: C:\Watch\~WRL3658.tmp

Other gotchas:

  • You should try to avoid watching a directory twice (i.e. as a directory and as a subdirectory) or you will double up on events.
  • UNC path names are not accepted on Windows NT 4.0 computers.
  • You cannot watch Windows 95 or Windows 98 directories.
  • I’ve seen it reported that if a user deletes a file using the Command Prompt as opposed to doing it using Explorer, it gives you the 8.3 file name instead in the event callback.  However, I have not been able to repeat this (but I’ve only tried 64 bit Windows 8).
  • FileSystemWatcher may not work on non-Windows file shares.  i.e. Novell drives.
  • Some applications (i.e., antivirus software) might cause additional file system events that are detected by FileSystemWatcher.

Going straight to the source

I looked at using the ReadDirectoryChangesW API as an alternative to the FileSystemWatcher.  However, the FileSystemWatcher is simply a wrapper around the API.  It seems that it has inherited all of its issues from the API.

Conclusion

Despite the list of gotcha above I will still be using the FileSystemWatcher.  It provides the change notifications I require and many of the drawbacks are not an issue for me.  But I will need to implement a directory scan to correct my data store (either as a nightly job or when the overflow occurs).

2 Comments

  • D N said

    Is FileSystemWatcher supported in Windows Server 2008 R2? I have a windows service that fires OnCreated event fine on a Windows 7 but not on Windows Server 2008 R2 machine. Is that event supported on 2008 R2?

  • Chris Shallcross said

    Hi D N,

    I have not seen any announcements from Microsoft about them removing this feature. I would be surprised if they did.

    I just using the FileSystemWatcher on a Windows 2008 R2 machine. The OnCreate event fired for me for files and directories. This was from a Windows form application rather than a service but I don’t see why that should make a difference.

    Are you getting a lot of change events? It’s possible that you’ve got an internal buffer overflow. You could try increasing the size of the internal buffer or reducing the amount of monitored changes by turning IncludeSubdirectories off or by reducing the NotifyFilter.

    Good luck.

    Chris

Add a Comment