Wednesday, 20 February 2008

Downloading and Deleting Temporary Files

Recently while working on some functionality for one of our clients I found myself in a position where I needed to add some images to a zip file. This zip file then needed to be sent to the end user as a download (Content-disposition: attachment;).

Once the user had downloaded the file, the zip file needed to be deleted so as not to leave temp files on the servers disk.

I tried a few things like calling File.Delete("path/to/") after doing Response.TransferFile() or Response.WriteFile() but I found that the page never loaded. I guess it was deleting the file bfore it had chance to stream the file to the client.

Eventually I came up with the code below which reads the entire file into a BinaryWriter and the write it out to the Response's OutputStream. The stream is then flushed and the file can be deleted.
    string theFile = "path/to/your.file";
FileInfo theFileInfo = new FileInfo(theFile);

if(theFileInfo.Exists) {
// Clear any output
Response.BufferOutput = true;
// should be the MIME-Type of your file
Response.ContentType = "application/x-zip-compressed";
// set the name of the file as it will be downloaded
Response.AddHeader("Content-Disposition", "attachment; filename=the.file");

// Open the OutputStream into a BinaryWriter
BinaryWriter br = new BinaryWriter(Response.OutputStream);
// Read the entire temporary file and write it into the BinaryWriter
// Flush and Close the Writer

// Fulsh the Response object

// Delete the temporary file
// End the execution of the page

While this does get the job done it isn't perfect. The entire file is read into memory before being sent to the client. This means if you are sending large files to many clients at the same time you could have some trouble with the server running out of memory and all manner of other crazy things happening (possibly).

As ever, use at your own risk.

1 comment:

  1. TransferFile is asynchronous. so, yes, you were deleting the file before it was done being used.