One of the great new features in ColdFusion 9 that I haven't seen much press about is it's Virtual File System. The virtual file system is essentially a RAM disk (remember back to DOS?). This allows you to do three really cool things. First. you can now write files such as images, spreadsheets, etc. to memory instead of disk before serving them back to the browser. Here's an example from the beta docs that shows this in use for writing a JPG file to memory and serving it up:
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<cffile action="readBinary" variable="myImage" file="#ExpandPath('./')#/blue.jpg">
<cffile action="write" output="#myImage#" file="ram://a.jpg">
<cfif FileExists("ram://a.jpg")>
<cfoutput>a.jpg exists</cfoutput>
<cfelse>
<cfoutput>a.jpg Doesn't exists</cfoutput>
</cfif>
1<cffile action="readBinary" variable="myImage" file="#ExpandPath('./')#/blue.jpg">
2<cffile action="write" output="#myImage#" file="ram://a.jpg">
3<cfif FileExists("ram://a.jpg")>
4 <cfoutput>a.jpg exists</cfoutput>
5<cfelse>
6 <cfoutput>a.jpg Doesn't exists</cfoutput>
7</cfif>
The second thing this lets you do is write dynamic .cfm files to memory and execute them. Again from the beta docs, to write a file you would do something like this:
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<cffile action="write" output="#cfml#" file="ram://filename.cfm"/>
1<cffile action="write" output="#cfml#" file="ram://filename.cfm"/>
How you use/execute an in-memory file depends on whether the tag/function you are using requires a relative or absolute path. For tags/functions that require a relative path, you need to first create a mapping for ram:// in the ColdFusion Administrator. Once you've done that, you simple use the mapping in the relative URL. For example if you create a mapping called /inmemory, you would use it within cfinclude like this:
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<cfinclude template="/inmemory/filename.cfm">
1<cfinclude template="/inmemory/filename.cfm">
For tags/functions that take an absolute path, the syntax is straightforward. From the beta docs:
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<cffile action="append" file="ram://a/b/dynamic.cfm" output="I'm appending">
1<cffile action="append" file="ram://a/b/dynamic.cfm" output="I'm appending">
The third thing you can do with the virtual file system is write and execute CFCs in memory. To write a CFC to the virtual file system you do the following, from the beta docs:
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<cffile action="write" output="#cfcData#" file="ram://filename.cfc"/>
1<cffile action="write" output="#cfcData#" file="ram://filename.cfc"/>
You execute the CFC like so:
ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org
<cfset cfc=CreateObject("component","inmemory.filename")/>
1<cfset cfc=CreateObject("component","inmemory.filename")/>
There are some limitations to the ram based file system. First and foremost, you can't write Application.cfm or Application.cfc to memory. Additionally, paths are case-sensitive.
The full list of tags that support the virtual file system are as follows:
- cfcontent
- cfdocument
- cfdump
- cfexchange
- cfexecute
- cffeed
- cfhttp
- cfftp
- cfimage
- cfloop
- cfpresentation
- cfprint
- cfreport
- cfzip
Supported file functions:
- FileIsEOF
- FileReadBinary
- Filemove
- Filecopy
- FileReadLine
- FileExists
- FileOpen
- FileWriteln
- FileClose
- FileRead
- FileDelete
- DirectoryExists
- FileSetLastModified
So, what do you all think? I think this opens up a lot of interesting possibilities, especially in terms of performance improvement.
7/13/09 1:59 PM
It would be handy for a "dump to file" tag, or command in some way. Let's say I build a bunch of things in RAM, but I want to run an occasional scheduled task to dump the RAM to disk, or vice-versa. Might could be used in conjunction with onApplicationStart and onApplicationEnd.
7/13/09 2:37 PM
Railo has had Virtual File Systems for a while. (http://classic.railo.ch/en/index.cfm?treeID=392)
Nice to CF catching up! ;)
7/13/09 2:50 PM
Thanks Eric. I was aware that Railo already had it. I'm just excited to see it in ColdFusion 9.
7/13/09 5:01 PM
Hey Rob,
You asked where this would be useful. One case I can think of in the project I work on (MXUnit) relates to testing private functions. When you want to test private functions you can use a function in mxunit called makePublic(). Under the hood, this generates a new .cfc on the fly, writes it to disk, and then does a createObject() on that thing. This new virtual file system would be nice to use for this, since it wouldn't require disk IO or cleanup.
Good stuff.
7/14/09 3:24 AM
I don't see a word on the scope of this.
Is it cleared after the request ?
Can it be shared between application ?
7/14/09 5:51 PM
@Mark, thanks! As you say, good stuff for sure.
@Bjorn, the virtual file system exists until you manually delete it. I'll do a follow up post on this...
7/15/09 8:07 PM
Waiting for a follow up post as I was gonna ask Bjorn's question like is it temporary, is it tied to an application or server, how would sandbox work it?
7/16/09 11:36 AM
@Qasim,
Check out <a href="http://www.brooks-bilson.com/blogs/rob/index.cfm/2... follow-up post</a> which should address most of those questions.