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.