Skip to main content
Ben Nadel at NCDevCon 2016 (Raleigh, NC) with: Ray Camden
Ben Nadel at NCDevCon 2016 (Raleigh, NC) with: Ray Camden ( @cfjedimaster )

Using Per-Application Mappings With File I/O In ColdFusion

By on
Tags:

Months ago, I had tweeted that I wished that per-application mappings in ColdFusion worked with file I/O operations, like fileRead() and fileWrite(). In response to said tweet, Tony Nelson replied that you can use the mappings with file I/O as long as you use it in conjunction with expandPath(). Unfortunately, I completely forgot this conversation until last week when I blogged about using expandPath() with ColdFusion's per-application mappings.

Since this is an awesome feature of the language, and one that I wasn't deeply aware of, I thought I should put together a quick demonstration. In the following app, I'm mapping a "storage" directory; then, I'm writing to and reading from it, respectively.

Application.cfc - Setting Up The Per-Application Mappings

<cfscript>

component
	output = false
	hint = "I define the application settings and event handlers."
	{

	// Define the application settings.
	this.name = hash( getCurrentTemplatePath() );
	this.applicationTimeout = createTimeSpan( 0, 0, 10, 0 );

	// Get the base directory so we can set up relative mappings.
	this.directory = getDirectoryFromPath( getCurrentTemplatePath() );

	// Set up a mapping for "storage". Notice that the actual directory
	// name is "data."
	this.mappings[ "/storage" ] = ( this.directory & "data/" );

}

</cfscript>

Notice that we set up a "/storage" mapping for the "data" directory. Now, we're going to write from and then read from that mapping:

Index.cfm - Our Test Page

<cfscript>

	logFile = ( timeFormat( now(), "HH-mm-ss" ) & ".txt" );

	// Log the request.
	writeDump(
		var = cgi,
		format = "text",
		output = expandPath( "/storage/#logFile#" )
	);

	// Gather the files in the "storage" directory.
	filePaths = directoryList( expandPath( "/storage" ) );

	// Output the file names so we can see which directory is actually
	// storing the files mapped via "/storage".
	for ( filePath in filePaths ) {

		writeOutput( filePath & "<br />" );

	}

</cfscript>

Here, I'm logging the CGI scope on each request and then listing the contents of the mapped directory. Notice that each file I/O operation uses the mapped directory; but, it passes through the expandPath() function first.

When we run the above code, we get the following page output:

/Sites/bennadel.com/testing/expand-path-io/data/08-44-20.txt
/Sites/bennadel.com/testing/expand-path-io/data/08-49-13.txt
/Sites/bennadel.com/testing/expand-path-io/data/08-49-14.txt
/Sites/bennadel.com/testing/expand-path-io/data/09-05-24.txt

Notice that the "/storage" mapping successfully mapped to the "data" directory.

This is one of those features that should have been part of my core understanding of the ColdFusion language. Unfortunately it was not; but, fortunately, it's never too late to learn. This is a very powerful feature and one that I will certainly take joy in using.

Want to use code from this post? Check out the license.

Reader Comments

4 Comments

Ben,

expandPath() on missing files/directories that use an IIS virtual directory resolves incorrectly in CF10. I just blogged about it if you want to link to my post.

expandPath() on missing files/directories that use a ColdFusion mapping has been fixed in CF10 (was a non-issue in CF9).

I don't advocate using an IIS virtual directory inside CF code, but that's the legacy environment I've inherited for the time being.

15,674 Comments

@Chris,

Feel free to link to your post! For sure! I don't have a lot of experience with virtual-directories, so I wouldn't be able to say one way or the other what works with them.

Definitely, though, I've used expandPath() a *lot* with missing files, outside of virtual directories. For example, when testing things, I'll usually have something like:

<cfset logFile = expandPath( "./log.txt" ) />
 
<cffile action="append" file="#logFile# ... />

And, the first run of the page, "log.txt" doesn't work. But, usually when testing things like this, I'm not using CF mappings.

That said, I'll stay away from virtual mappings :D

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel