Blaine the Train asks:
I need to find the size of a given folder. In CF7, that's easy enough, but I'm still using 6.1. Any ideas to get me the size of a specific folder?
In case you aren’t aware, when Blaine says this is easy to do in CFMX7, he is talking about the new recurse=true attribute to cfdirectory. This lets you get a directory and all subdirectories and files. Very handy. I think that a lot of cool code stuff got overlooked (PR wise) in CFMX7, and this is one of them. (Of course, I’m a geek, and while I think Enterprise Gateways are super-cool, I use isValid every single day.) So since we don’t have the recurse attribute in CF6, what can we do? Simply write our own recursive function. Here is the code I wrote for directoryList over at CFLib.
cffunction name="directoryList" output="false" returnType="query">
<cfargument name="directory" type="string" required="true">
<cfargument name="filter" type="string" required="false" default="">
<cfargument name="sort" type="string" required="false" default="">
<cfargument name="recurse" type="boolean" required="false" default="false">
<!--- temp vars --->
<cfargument name="dirInfo" type="query" required="false">
<cfargument name="thisDir" type="query" required="false">
<cfset var path="">
<cfset var temp="">
<cfif not recurse> <cfdirectory name="temp" directory="#directory#" filter="#filter#" sort="#sort#"> <cfreturn temp> <cfelse> <!--- We loop through until done recursing drive ---> <cfif not isDefined("dirInfo")> <cfset dirInfo = queryNew("attributes,datelastmodified,mode,name,size,type,directory")> </cfif> <cfset thisDir = directoryList(directory,filter,sort,false)> <cfif server.os.name contains "Windows"> <cfset path = "\"> <cfelse> <cfset path = "/"> </cfif> <cfloop query="thisDir"> <cfset queryAddRow(dirInfo)> <cfset querySetCell(dirInfo,"attributes",attributes)> <cfset querySetCell(dirInfo,"datelastmodified",datelastmodified)> <cfset querySetCell(dirInfo,"mode",mode)> <cfset querySetCell(dirInfo,"name",name)> <cfset querySetCell(dirInfo,"size",size)> <cfset querySetCell(dirInfo,"type",type)> <cfset querySetCell(dirInfo,"directory",directory)> <cfif type is "dir"> <!--- go deep! ---> <cfset directoryList(directory & path & name,filter,sort,true,dirInfo)> </cfif> </cfloop> <cfreturn dirInfo> </cfif> </cffunction> </code>
This works well, but probably isn’t the best code to run on the root of a drive. Once you have the query, to get the total size, you could simply use query of query to get the sum of the file size.
Now that’s the CFML solution. While slow, it will work in all platforms. The quickest solution would be to write up a quick bat file and fire off a cfexecute to run it. Or potentially use a COM object if you are on Windows. (Here is a COM example: http://www.cflib.org/udf.cfm?ID=120) These solutions would probably run a heck of a lot faster, but will tie you to one OS. Frankly I don’t think that is a big huge deal. While I know people who have switched database types, I don’t know many who have switched operating systems. And if you are using proper code encapsulation techniques, you can always replace an OS specific call with a CFML one.