locked
Can't delete files sent via TransmitFile! RRS feed

  • Question

  • User877999272 posted

    Hey All,

    Here's the problem. I've got a web site that pushes downloadable files to our customers. Currently the code to push looks like this:

    response.Clear();
    response.ContentType = CONTENTTYPE;
    response.AddHeader("content-disposition", String.Format("attachment;filename={0}", FILENAME));
    response.AddHeader("content-length", FILELENGTH);
    response.TransmitFile(FILEPATH);
    response.Flush();
    response.End();

    This solution works quite well except for one teeny little problem...these files can be updated frequently, and TransmitFile locks the file while someone is downloading it, making it unable to be updated.

    So to fix this, I tried copying the file to a temp location, calling TransmitFile on the temp file, and then deleting the temp file. But it seems as if TransmitFile runs asynchronously, and it is never able to delete the file, throwing exceptions in the process. Same result with WriteFile. Same result if I throw a response.close in there, too.

    Is there a way to tell when those files are done transmitting? I've seen plenty of ways to handle downloads, and none seem to fit the requirement of not locking the file. One thing I like about the TransmitFile method is that since it runs asynchronously, it doesn't hamper the performance of the rest of the site...the handler is freed up, where if I read the file and wrote into the output stream, that handler would be unavailble until the file is done or the client disconnects. Is that accurate?

    Any help would be appreciated.

    Thanks,
    John

    Monday, October 2, 2006 4:42 PM

Answers

  • User1622957740 posted

    That's part of the reason for using TransmitFile() - it clears the ASP.NET queue of the request and lets ISAPI (or IIS) deal with feeding the file back to the client more efficiently. THere's really no way to change this - it's meant for static files.

     What I do in situations like this is store the file in temp folder and not worry about deleting it immediately. Instead I use a routine at the beginning of this file transfer to scan through the directory and delete any files that are older than a given time (usually like a few minutes, depending on the size of your files. As an alternative you can try to delete everything that can be deleted and isn't locked). This isn't exactly a 'clean' implementation but it works fine at ensuring that you won't end up with a pile of temporary files. At most you'll have two minutes (or whatever) worth of files in the temp directory.

     Small price to pay for the ability to use TransmitFile on large non-static files.

     If your files aren't large then you're better off not bothering with Transmit file - just stream them directly into Response.OutputStream.

    +++ Rick ---

     

     

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, October 2, 2006 6:08 PM

All replies

  • User1622957740 posted

    That's part of the reason for using TransmitFile() - it clears the ASP.NET queue of the request and lets ISAPI (or IIS) deal with feeding the file back to the client more efficiently. THere's really no way to change this - it's meant for static files.

     What I do in situations like this is store the file in temp folder and not worry about deleting it immediately. Instead I use a routine at the beginning of this file transfer to scan through the directory and delete any files that are older than a given time (usually like a few minutes, depending on the size of your files. As an alternative you can try to delete everything that can be deleted and isn't locked). This isn't exactly a 'clean' implementation but it works fine at ensuring that you won't end up with a pile of temporary files. At most you'll have two minutes (or whatever) worth of files in the temp directory.

     Small price to pay for the ability to use TransmitFile on large non-static files.

     If your files aren't large then you're better off not bothering with Transmit file - just stream them directly into Response.OutputStream.

    +++ Rick ---

     

     

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, October 2, 2006 6:08 PM
  • User877999272 posted

    Rick,

    That's kindof where I was thinking this was going to have to go.

    Just out of curiosity, where would you draw the line between using TransmitFile and writing directly to the output stream? Our files are mostly pretty small...under 3MB. Then there's installers in the ~10MB area, and then a few that are over 100MB.

    Thanks,
    John

    Monday, October 2, 2006 6:36 PM