Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at CFUNITED 2010 (Landsdown, VA) with:

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

By Ben Nadel on
Tags: ColdFusion

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.


 
 
 

 
ExpandPath() I/O tweet. 
 
 
 

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.




Reader 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.

Reply to this Comment

@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

Reply to this Comment

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.