A while back, I had read about replacing CFDirectory functionality with Java over on ColdFusion Muse. This is a cool idea and I have never played around with it, so I figure I might as well sit down and do a little demo for myself.
I happen to Love CFDirectory. I think it's a fabulous tag. The one thing I really hate about it though, is that it is not really structured in any useful way. It returns the whole directory structure in ONE massive query. As part of my File Explorer project (yes, I WILL finish that one day), I would love the ability to get a representation of a directory and sub-directories / files in some sort of structure that made more sense in my head.
To accomplish this, I have created a ColdFusion user defined function, GetDirectoryXML(), that recurses over a directory (the recursion itself is optional) and creates an XML document in this format:
Launch code in new window » Download code as text file »
For things like the Name and Path attributes, I opted for using XML node attributes over text nodes because XPath searches are much easier on attributes (at least at my low-xml-xpath-skill level). I like the above structure because it becomes very clear where all the files and directories belong. Also, If I wanted to render this XML it provides a great structure that has sub-structures that I could pass off to a recursive function for rendering.
Here is the code for the GetDirectoryXml() ColdFusion function:
Launch code in new window » Download code as text file »
You might notice that one of the arguments is an optional Java StringBuffer object. Internally, the UDF writes all the directory XML to a String Buffer which it then passes around recursively. This is done to minimize the amount of string concatenation that is being done. If you pass in a String Buffer object, the GetDirectoryXml() UDF will not return anything as you will already have a pointer to the String Buffer object. I like this flexibility, but not sure that it would be useful (other than for performance).
Calling the GetDirectoryXml() UDF on a simple directory might return something like this:
| | | | ||
| | ![]() | | ||
| | | |
Notice the highly structured data. Even though it is structured in this nested way, you can still use XPath to search for files just as you could with a ColdFusion query of queries using CFQuery:
Launch code in new window » Download code as text file »
This will return an array of File XML nodes whose name attribute is "set.cfm" regardless of where in the structure it is.
Now, I mentioned that a highly structured XML directory representation could be easily rendered. This is another ColdFusion UDF that I have created in order to render the XML generated by GetDirectoryXml(). It's called RenderDirectoryXml():
Launch code in new window » Download code as text file »
This produces an output that looks like:
| | | | ||
| | ![]() | | ||
| | | |
I think this is going to come in quite handy for finishing my blasted File Explorer. Thanks Mark Kruger!
Download Code Snippet ZIP File
Comments (10) | Post Comment | Ask Ben | Permalink | Other Searches | Print Page
Hi
I noticed that you were looking to create a file/directory explorer and thought this might be of help (it's free).
I had to put it together for a recent client and it is prettey polished.
Here is the link: http://www.netgrow.com.au/assets/files/explorer/explorer.zip
Posted by Shuns on Feb 1, 2007 at 5:53 PM
Shuns,
It is hard kicking so much ass? Cause that's probably the cleanest, coolest file explorer I have ever seen. I had a tiny bit of trouble figuring out how to set up the path, but got it going. You might want to throw a comment in there or a little demo snippet so people know what you are talking about. Very cool though!
Posted by Ben Nadel on Feb 2, 2007 at 12:25 PM
Yeah I know but I was just trying to send it quick otherwise I would have documented it.
Posted by Shuns on Feb 4, 2007 at 5:47 PM
No worries dude, it was way cool.
Posted by Ben Nadel on Feb 4, 2007 at 9:14 PM
There is a call to fx called ListFiles. Where does that come from?
Posted by Derek on Feb 16, 2007 at 5:46 PM
Derek,
It is a method of the Java File Object:
http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html#listFiles(java.io.FileFilter)
It returns an array of File objects that live within that directory.
Posted by Ben Nadel on Feb 16, 2007 at 5:49 PM
hmm....well i get this error on it...
"The selected method ListFiles was not found"
Posted by Derek on Feb 16, 2007 at 5:58 PM
Hmmm. That's odd. You are probably not passing in a File object to the method. The argument [Directory] needs a File object, NOT a file path:
Directory = CreateObject( "java", "java.io.File" ).Init( ExpandPath( "./directory_name_here/") )
You might be passing in just the ExpandPath() stuff in.
Am I close?
Posted by Ben Nadel on Feb 16, 2007 at 6:14 PM
just getting back to this now. Yes, that was the problem.
I have one small problem though. When I run it through the renderer, if I have a structure like this in my FS...
Folder_DOCS
--doc1
--doc2
----Folder_DOCS_Sub
------doc1
------doc2
----------Folder_DOCS_Sub_sub
------------doc1
------------doc2
it ends up outputting like this
Folder_DOCS
----Folder_DOCS_Sub
----------Folder_DOCS_Sub_sub
------------doc1
------------doc2
------doc1
------doc2
--doc1
--doc2
how can i make it exactly replicate the FS stucture?
Posted by Derek on Feb 26, 2007 at 11:55 AM
Derek,
I will make a folder structure as you describe and try running it. I am sure it's a minor bug. Thanks for the heads up. I will get back to you.
Posted by Ben Nadel on Feb 26, 2007 at 12:12 PM