Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at cf.Objective() 2012 (Minneapolis, MN) with: Alec Irwin
Ben Nadel at cf.Objective() 2012 (Minneapolis, MN) with: Alec Irwin

GetTempFile() Creates 0KB Files In ColdFusion

By Ben Nadel on
Tags: ColdFusion

The other day, I happened to notice that a few of our servers had thousands of 0KB files in the temp-directory. After I was able to track down the code that was creating the temp files, I quickly realized what the problem was - the developer thought that the getTempFile() function simply returned a temporary file path; he was not aware (or was not thinking about the fact) that getTempFile() actually creates a file, albeit 0-bytes in size, when called.

The code that I found looked something like this:

  • <cfscript>
  •  
  • /**
  • * I do some processing with some temporary files.
  • *
  • * @output false
  • */
  • public void function processRequest( required numeric input ) {
  •  
  • // Get a scratch file in the temp directory that we can use to process the input.
  • var tempFilePath = getTempFile( getTempDirectory(), "processing-#input#-" );
  •  
  • lock
  • name = "processingRequest"
  • type = "exclusive"
  • timeout = 1
  • {
  •  
  • try {
  •  
  • // Do some processing that may cause the parent LOCK to timeout on
  • // subsequent requests.
  • sleep( 5 * 1000 );
  •  
  • // No matter what happens, clean up the scratch file.
  • } finally {
  •  
  • fileDelete( tempFilePath );
  •  
  • }
  •  
  • } // END: Lock.
  •  
  • }
  •  
  •  
  • // ------------------------------------------------------ //
  • // ------------------------------------------------------ //
  •  
  •  
  • processRequest( 4 );
  •  
  • </cfscript>

As you can see, the code makes a good effort to clean-up after itself, deleting the scratch file in the Finally clause of the Try/Catch block. And, if you thought that getTempFile() only returned a file path, this would likely be sufficient. But, since getTempFile() actually creates a file and returns the resultant path, this code has the potential to leave scratch files laying around.

Once you concentrate on the fact that getTempFile() creates a file, it becomes clear that if the control flow can't obtain the Lock, due to the timeout, then the Try/Catch block is never entered. And, if the Try/Catch block is never entered, the Finally block is never executed which means that the temp file is never cleaned-up.

This is what was happening in our code. Luckily, the fix is quite easy - all we have to do is move the getTempFile() request into the Try/Catch block. Doing so will ensure that the temp file only ever gets created in a context that can be cleaned-up:

  • <cfscript>
  •  
  • /**
  • * I do some processing with some temporary files.
  • *
  • * @output false
  • */
  • public void function processRequest( required numeric input ) {
  •  
  • lock
  • name = "processingRequest"
  • type = "exclusive"
  • timeout = 1
  • {
  •  
  • try {
  •  
  • // Get a scratch file in the temp directory.
  • var tempFilePath = getTempFile( getTempDirectory(), "processing-#input#-" );
  •  
  • // Do some processing that may cause the parent LOCK to timeout on
  • // subsequent requests.
  • sleep( 5 * 1000 );
  •  
  • // No matter what happens, clean up the scratch file.
  • } finally {
  •  
  • fileDelete( tempFilePath );
  •  
  • }
  •  
  • } // END: Lock.
  •  
  • }
  •  
  •  
  • // ------------------------------------------------------ //
  • // ------------------------------------------------------ //
  •  
  •  
  • processRequest( 4 );
  •  
  • </cfscript>

It's a minor change, but it makes all the difference. Ultimately, though, you just have to realize that the getTempFile() function both creates a file and returns a file path.

Tweet This Groovy post by @BenNadel - GetTempFile() Creates 0KB Files In ColdFusion Thanks my man — you rock the party that rocks the body!



Reader Comments

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.