Skip to main content
Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.

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.



Reader Comments