views:

167

answers:

2

We're replacing an "old" web application (the original CodeCentral was written over 10 years ago, now running at http://cc.embarcadero.com with over 12.7 million served) that uses a file based cache for serving downloads. The web application manages this file cache.

The only complicated bit of using file-based downloads is updating a file that might be in use by another version. Back when I wrote the the original Delphi CGI version of CodeCentral, I vaguely recall being able to rename the existing file even though someone might be downloading it, writing the new file with the correct name, and eventually cleaning up the old file.

However, I may be delusional, because that's not working with our current IIS 6 and ASP.NET 2.x or 3.x code. So, what we've done instead is this, which is quite kludgy but eventually works:

public static void FileCreate(Stream AStream, string AFileName, int AWaitInterval)
{
  DateTime until = DateTime.Now.AddSeconds(AWaitInterval);
  bool written = false;
  while (!written && (until > DateTime.Now))
  {
    try
    {
      using (FileStream fs = new FileStream(AFileName, FileMode.Create))
      {
        CopyStream(AStream, fs);
        written = true;
      }
    }
    catch (IOException)
    {
      Thread.Sleep(500);
    }
  }
}

I'm thinking we're missing something simple and there's got to be a better way to replace a file currently being downloaded via IIS and ASP.NET. Is there?

A: 

John, Could you shed a bit more light on the situatuation?

If the files are small enough you could load the entire file into memory then send it to the client.

Maybe this blog post about downloading and deleting temporary files will help a little.

Greg B
Thanks for asking, Greg. These are large files, 500MB or more. Furthermore, they're not temporary files, but rather files that sometimes need to be updated. Most of the files don't change, but when they do, we need to be sure we can replace them with a new version. Your question prompted me to think about this again - perhaps we can embed a version stamp into the file and solve it that way.
John Kaster
+2  A: 

I think we're going to resolve this with the following logic:

We store the date/time a file is updated. If we're unable to update the data-driven file name "[id].zip", we'll create "[id]_[modified].zip" instead, and use that until we're able to rename it to "[id].zip" by deleting the older version of the file.

That way, we're always assured of the latest file by first looking for "[id]_[modified].zip" before looking for "[id].zip", and we can easily implement a clean-up routine both on demand and in the background even if there are multiple modified versions before we can finally replace the "standard" "[id].zip" version.

Of course, this only works if you store the last time the file was modified, but any system using this type of technique should anyway.

John Kaster