File in use: How to tell.

  • Thread starter Thread starter Daniel Reber
  • Start date Start date
D

Daniel Reber

I have an application that is sending a file to a location on a network. I
have a windows service that is monitoring that location for new files and
then processing them. Sometimes the service tries to process them before
that are copied over completely. How can I tell if the other application is
done copying the file over?

Thanks

Dan Reber
 
private const string RETRY_MAX_TIME_EXCEEDED = "The file \"{0}\" could not
be processed because a timeout occurred while waiting for the file to finish
uploading.";

private const int RETRY_MAX_TIME = 3600000; // 1 hour
private const int RETRY_DELAY = 10000; // 10 seconds

/// <summary>
/// The event handler that is called when a new file has been uploaded to
the
/// watched directory.
/// </summary>
private void FileCreated(object sender, FileSystemEventArgs args)
{
string filename = args.FullPath;
DateTime receivedAt = DateTime.Now;

bool timedOut = false;
bool processed = false;

//
// The event will be raised as soon as the first byte is written to the
file.
// Check to see if the file has completed uploading. If it hasn't, wait
for a
// specified delay and check again.
//
while (!(timedOut || processed))
{
if (FileUploadCompleted(filename))
{
ProcessFile(filename);
processed = true;
}
else
{
TimeSpan timeElapsed = DateTime.Now - receivedAt;

if (timeElapsed.TotalMilliseconds > RETRY_MAX_TIME)
{
timedOut = true;
}
else
{
Thread.Sleep(RETRY_DELAY);
}
}
}

if (timedOut)
{
LogError(String.Format(RETRY_MAX_TIME_EXCEEDED, filename));
}
}

/// <summary>
/// Returns true if the specified file has completed uploading and is ready
for
/// processing.
/// </summary>
private bool FileUploadCompleted(string filename)
{
//
// If the file can be opened for exclusive access it means that the file
// is no longer locked by the FTP server program and has completed
uploading.
//
try
{
using (FileStream inputStream = File.Open(filename, FileMode.Open,
FileAccess.Read,
FileShare.None))
{
return true;
}
}
catch (IOException)
{
return false;
}
}
 
Add the code in the service, which will examine why it fails. If file is in
use service has to wait until it is released and retry attempt to access
file. Of course, you'll need to use also timeouts - you can't wait
indefinitely, right?

HTH
Alex
 
Back
Top