How to monitor a folder for new files from your C# application

Suppose that you need to write a C# application to run in an environment where there are many batch applications running and creating files as their output.

Your application is one of them and is required to process files produced by others. How are you going to know from your C# application when these files are ready?

In this post, I document the use of a .Net facility that can help you achieve that.

The FileInputMonitor class

Let us create a sample use case. Suppose there is a folder which other applications will deposit their file output on a daily basic. The naming convention of the file will be report-for-<CURRENT_DATE-YYYY-MM-DD>. For instance, on 7th April 2012, the file will be named as report-for-2012-04-07.

The following FileInputMonitor class is an implementation for the sample use case.

using System;
using System.IO;
using System.Text;
using System.Threading;

public class FileInputMonitor
{

    private FileSystemWatcher fileSystemWatcher;
    private string folderToWatchFor 
        = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "toTechcoil";

    public FileInputMonitor()
    {

        fileSystemWatcher = new FileSystemWatcher(folderToWatchFor);
        fileSystemWatcher.EnableRaisingEvents = true;

        // Instruct the file system watcher to call the FileCreated method
        // when there are files created at the folder.
        fileSystemWatcher.Created += new FileSystemEventHandler(FileCreated);

    } // end FileInputMonitor()

    private void FileCreated(Object sender, FileSystemEventArgs e)
    {

        if (e.Name == "report-for-" + System.DateTime.Now.ToString("yyyy-MM-dd")) 
        {
            ProcessFile(e.FullPath);
        } // end if

    } // end public void FileCreated(Object sender, FileSystemEventArgs e)

    private void ProcessFile(String fileName)
    {
        FileStream inputFileStream;
        while (true) 
        {
            try
            {
                inputFileStream = new FileStream(fileName, 
                    FileMode.Open, FileAccess.ReadWrite);
                StreamReader reader = new StreamReader(inputFileStream);
                Console.WriteLine(reader.ReadToEnd());
                // Break out from the endless loop
                break;
            }
            catch (IOException)
            {
                // Sleep for 3 seconds before trying
                Thread.Sleep(3000);
            } // end try
        } // end while(true)
    } // end private void ProcessFile(String fileName)
   
} // end public class FileInputMonitor

Monitoring whether new files are created in a folder with System.IO.FileSystemWatcher

When an instance of FileInputMonitor is created, we also create an instance of System.IO.FileSystemWatcher class, passing it the directory path of the folder to monitor.

After creating an instance of the FileSystemWatcher, we proceed to configure it. In order to enable the FileSystemWatcher instance to notify our application when files are created in the folder, we must first set its EnableRaisingEvents property to true.

We then add a System.IO.FileSystemEventHandler delegate to the Created event so that control can be delegated to the FileCreated method of our FileInputMonitor class whenever a new file is created.

Checking whether an expected file is ready for processing

When the FileCreated method is executed, we check whether the new file is what our application wants via the Name property of the System.IO.FileSystemEventArgs instance. If the file is designated for our application, the ProcessFile method is called to process the file.

In the ProcessFile method, we attempt to get an instance of System.IO.FileStream with ReadWrite access to read from the file in an infinite loop. This is because the batch application may still be writing to the file when our application received notification of the new file.

In the event when the instance of FileStream cannot be retrieved, the application will wait for 3 seconds via a call to Thread.Sleep. Upon success acquisition of the FileStream instance, the code reads from the file, output it to console and break out of the infinite loop.

Using the FileInputMonitor class

To conclude this post, the following is a program that maintains an instance of the FileInputMonitor to monitor the toTechcoil folder that is in the same directory as the executable.

public class Program
{
    public static void Main(string[] args)
    {
        FileInputMonitor fileInputMonitor = new FileInputMonitor();
        Console.Read();
    } // end public static void Main(string[] args)

} // end public class Program

Other posts that may interests you

Advertisements

About Clivant

Clivant a.k.a Chai Heng enjoys composing software and building systems to serve people. He owns techcoil.com and hopes that whatever he had written and built so far had benefited people.

4 Comments

  • Dan Dorset
    May 8, 2013 at 1:50 am

    This is very helpful, thank you!

    • Clivant
      May 11, 2013 at 9:14 pm

      Hi Dan,

      You are welcomed. 🙂

  • Vikas
    December 21, 2013 at 3:12 pm

    this info is very useful

    • Clivant
      December 27, 2013 at 5:09 pm

      Hi Vikas,

      Glad that this article had helped you. 🙂

Advertisements
Advertisements