Using Per-Application Mappings With File I/O In 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.
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
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.
@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:
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
@Ben,
Thanks for allowing me to post the link.
@Everyone,
Here's the link to my blog post explaining the expandPath() VD issue:
http://cfweller.blogspot.com/2013/09/cf10-expandpath-issue-with-iis-virtual.html