FileSystemWatcher Tips

The .NET FileSystemWatcher class makes it possible to quickly and easily launch business processes when certain files or directories are created, modified, or deleted. The FileSystemWatcher class, for example, can be quite useful in application integration, by way of monitoring incoming data files and processing it once an event is raised. It listens to the file system change notifications and raises events when a directory, or file(s) in a directory, changes. The component can watch files on a local computer, a network drive, or a remote computer.

I've come to realize that it does need some understanding of this class to make it work efficiently. For example, a denial-of-service attack is possible if a malicious program gains access to a directory the FileSystemWatcher component is monitoring, and which thereby generates so many changes that the component cannot manage them and can cause a buffer overflow or other drastic effects. Following are some tips and notes on how to use the FileSystemWatcher class to build a more robust solution:

1. Events being raised twice - An event will be raised twice if an event handler (AddHander FSW.Created, AddressOf FSW_Created) is explicitly specified. This is because, by default, the public events automatically call the respective protected methods (OnChanged, OnCreated, OnDeleted, OnRenamed). To correct this problem, simply remove the explicit event handler (AddHandler ...).

2. Events being raised multiple times - In some cases a single event can generate multiple events that are handled by the component. Because FileSystemWatcher monitors the operating system activities, all events that applications fire will be picked up. For example, when a file is moved from one directory to another, several OnChanged and some OnCreated and OnDeleted events might be raised. Moving a file is a complex operation that consists of multiple simple operations, therefore raising multiple events. Such multiple events can be correctly handled and processed by using a simple boolean flag check (for a first-come-first-serve approach) or by setting the FileSystemWatcher.NotifyFilter property to one of the NotifyFilters values.

3. Thread Safety - Any public static (Shared in VB) members of this class type are thread safe. Any instance members are not guaranteed to be thread safe.

4. File System Type - The FileSystemWatcher does not raise events for CDs and DVDs, because time stamps and properties cannot change for such media types.

5. Filter - The Filter property can be used to watch for changes in a certain type(s) of file(s) (eg: "*.txt"). To watch for changes in all files, set the Filter property to an empty string (""). Hidden files are also monitored by the FileSystemWatcher.

6. Internal Buffer - The FileSytemWatcher component uses an internal buffer to keep track of file system actions. You should set the buffer to an appropriate size for the approximate number of events you expect to receive. By default, the buffer is set to a size of 4 KB. A 4 KB buffer can track changes on approximately 80 files in a directory. Each event takes up 16 bytes in the buffer, plus enough bytes to store the name of the file, in Unicode (2 bytes per character), that the event occurred on. You can use this information to approximate the buffer size you will need. You (re)set the buffer size by setting the InternalBufferSize property. If there are many changes in a short time, the buffer can overflow. This causes the component to lose track of changes in the directory, and it will only provide blanket notification. Increasing the size of the buffer is expensive, as it comes from non-paged memory that cannot be swapped out to disk, so keep the buffer as small as possible. Setting the Filter does not decrease what goes into the buffer. If you are using Microsoft Windows 2000, you should increase the buffer size in increments of 4 KB, because this corresponds to the operating system's default page size. With any other operating system, you should increase the buffer size in increments that correspond to the operating system's default page size. If you are unsure of the default page size for the operating system you are using, the safest way to proceed is to just double the original size of the buffer. This will maintain the original interval needed for your operating system.

7. Directories - Changing a file within a directory you are monitoring with a FileSystemWatcher component generates not only a Changed event on the file but also a similar event for the directory itself. This is because the directory maintains several types of information for each file it contains - the names and sizes of files, their modification dates, attributes, and so on. Use the IncludeSubdirectories property to indicate whether or not you want to include the subdirectories of the directory you are watching. If you turn this off when you do not need it, you will receive fewer events than when it is turned on.

8. Stop Watching - When file system monitoring is not needed anymore, you should set the EnableRaisingEvents property to False to disable the component, otherwise the component will continue listening.

The FileSystemWatcher class provides a useful feature but it should be implemented along with a thorough examination.

19 Comments

  • Ashutosh,

    Good comment, i will note of this.



    Thanks and regards,



    Suresh




  • Never knew such a class existed. Good Stuff !!

  • If you are trying to respond to new files that get created in a directory, try watching for a FileChange event on the directory itself. Any files created in the directory will cause a change int he directory and you can then use the System.IO.Directory.GetFiles() method to look at the files in the directory and act appropriately.



    Here's some code...



    private void FileChanged(object sender, System.IO.FileSystemEventArgs e)

    {

    string[] strNames;



    strNames = System.IO.Directory.GetFiles(e.FullPath);



    if ( strNames.Length > 0 )

    {

    // Do what you want here. I would suggest moving the files to another directory and then passing

    // the new path names to some object that is running on another thread.

    // You'll get more events because the directory is changing but strNames will be empty in the subsequent

    // events (unless there are more new files to process).

    }

    }

  • Nice post! By-the-way, FileSystemWatcher is just a wrapper around the ReadDirectoryChangesW API call. This is the same API that's used when you open an Explorer window on a mapped server drive, and it shows newly added files. This is an event-based API implemented with SMB messages, not a polling API.

  • how does filesystemwatcher react when 2 simultaneous file action raise the event?

  • Can someone help me with the following problem:



    I have created a FileSystemWatcher (fsw) to monitor creation of *.txt file on a mapped directory (the directory is on a Win98 system) the application works fine (events are triggering) when it is running on a XP system, but the same application did not get any event trigger when it is runnig on a Win2K system. Any idea?

  • actually, i'm running this FSW on a win server 2003, it seems to "randomly" select when it will trigger the events.



    any ideas?

  • As mentioned, the FileSystemWatcher is just a wrapper around ReadDirectoryChangesW, and this API call isn't supported on 98 or ME.

  • "...remove the explicit event handler..."



    Could you elaborate on this a bit more? I'm using the FileSystemWatcher in C# and I'm finding that the Changed event is the biggest problem because it often gets fired twice. It sounded like you were onto something, but I didn't get the gist of it.

  • If I'm watching a directory where large files are routinely placed, will the changed even get fired repeatedly as the files are copied/uploaded?

  • Like other s**t from Microsoft you need to "hack" to do something work corect.

    "To correct this problem, simply remove the explicit event handler (AddHandler ...)."



    but I really need this handler i cant removed ...

  • There seems to be huge inconsistency when I run a FSW on Windows 2003 Server box, as opposed to a Windows XP box, both of which are monitoring a network share directory. Windows XP box seems to pick up 1000 file change events, whereas, Windows 2003 box seems to pick up only 250 events.



    Does anybody know of any network file event conditions on Windows 2003, that could be causing this?



    Is it generally a bad idea to watch for file change events over the network?



    Any ideas or suggestions will help.

  • I tried to delete a file, when the created event gets fired, it does not allow me to delete this file because it says file used by another process.

    Does anyone have idea of how to solve this problem?

    To elaborate what I am trying to do. I listen for incoming files, once the files are dropped, I pick them up, update the database then delete the file(s). The problem I am facing is deleting the file. I have a sneak feeling the the FileSystem watcher has a hold on this file in Memory. I even tried renamining it, so that I can delete the renamed file at a later stage. It did not allow me to rename either

  • More then likely, something still has a reference to your file. How are you inserting the file into the database? If you are using a StreamReader object, then make sure you .Close() it before you attempt to File.Delete() your file.

  • Hi,



    Liked your article.. in my case files are being copied to source directory (its on network).. and then moved to target directory automatically using FSW.. If the files being copied to source directory are big then, event is being fired but since whole file is not yet copied to source, it result into an error while moving to target.. any idea how to solve this error.



    regards,

    Nilay

  • I make my own file watcher to control the creation, modification, changes and rename of a file in a floppy drive, but cannot control the read access. Someone can help me???

  • Thanks for using the magic word "subdirectory." I think you just saved me a bunch of work.



    hln

  • Good tips but this class seems to not work 100% of time. This thing missed several files created in a directory I was watching.

  • Any idea, how to monitor a network folder, that require user name and password for access?

Comments have been disabled for this content.