File System Watcher in C#
There is often a requirement to watch files on an FTP folder
and process the file as soon as it arrives.
This can be achieved in two ways.
Pull Mechanism – for e.g, using Timers, i.e checking the file arrival in its time elapsed event.
Push Mechanism –for e.g using File System Watcher object.
Pull Mechanism – for e.g, using Timers, i.e checking the file arrival in its time elapsed event.
Push Mechanism –for e.g using File System Watcher object.
Both pull and push has its own merits and demerits. One of
the biggest drawback of pull mechanism, being the need to check for files at
regular interval of time. Which means there is hit at the server periodically and the
service consumes system resources unnecessarily.
File system watcher does not fully solve the problem either.
The file system watcher is designed in such a way that it triggers an event as
soon as there is any activity in the watched folder. In cases where the file
size is big and it takes time to upload, processing of the file fails, since
it is still being uploaded.
One way to cater to this problem is by blending the Push and
Pull mechanism, i.e use of File system watcher and timer both.
File system
watcher triggers an event for any file arrival in the c# application. Which
thereby starts a timer. This timer is on demand basis. The timer would check if the file has been uploaded
fully and once done, processe the file. Once all file as processed, stops
would itself and wait for another on demand request from File System Watcher.
Sample Code:
FileSystemWatcher fileWatcherFTP = new FileSystemWatcher();
fileWatcherFTP.Path = directoryToWatch;
fileWatcherFTP.Filter = "*.xml";
fileWatcherFTP.IncludeSubdirectories = true;
fileWatcherFTP.Created += new FileSystemEventHandler(fileWatcherFTP_Changed);
fileWatcherFTP.Changed += new FileSystemEventHandler(fileWatcherFTP_Changed);
fileWatcherFTP.EnableRaisingEvents = true;
timerFTP = new System.Timers.Timer(60000);
timerFTP.Enabled = true;
timerFTP.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timerFTP.Start();
void timer_Elapsed(object
sender, System.Timers.ElapsedEventArgs e)
{
processFile
();
}
private void
processFile()
{
try
{
DirectoryInfo directoryInfo = new DirectoryInfo(directoryToWatch);
FileInfo[] files =
directoryInfo.GetFiles();
if (files.Count() == 0)
{
// Stop Timer when all files has been processed
timerFTP.Stop();
timerFTP.Enabled = false;
}
else
{
foreach (FileInfo
fileInfo in files)
{
if (fileUploadCompleted(fileInfo.FullName)) // Check if the upload is complete.
{
// process file
}
}
}
}
catch (Exception
ex){}
}
private bool
fileUploadCompleted(string filename)
{
try
{
using (FileStream
inputStream = File.Open(filename, FileMode.Open, FileAccess.Read,
FileShare.None))
{
return true;
}
}
catch (IOException)
{
return false;
}
}