ColdFusion DirectoryList () - is it possible to get only directories?

7.1k Views Asked by At

I've used <cfdirectory> to get only directories, but I need to do this inside a UDF written in cfscript, so I need to use DirectoryList(). It appears that I need to get everything and then visit the result filtering directories manually. However, there is a filter parameter... can it be used to filter only directories? If so, what would be the filter?

I haven't found an example that will return only directories, and the documentation is not clear on what can be filtered (except for *.txt).

5

There are 5 best solutions below

1
Leigh On BEST ANSWER

Unfortunately, no. Unlike cfdirectory's type attribute, filters are only applied to the file/directory names. So I do not think it is possible to use filter to find directories only. Keep in mind you can always wrap cfdirectory in a function, then call it from your UDF. That is what the old DirectoryList function at cflib.org does.

the documentation is not clear on what can be filtered (except for *.txt).

You can only search the name. filter supports partial patterns (like find files containing "xxx"), searching by file extensions, or you could apply multiple patterns by using "|":

*test*        // partial pattern. names containing the word "test"
*.xls         // find Excel files
*test*|*.xls  // find names containing "test" OR Excel files

However, since the pattern is only applied to the name, it cannot be used to reliably identify directories.

5
ale On

<cfdirectory action="list"...> (and DirectoryList(path [,recurse] [,listInfo="query"]...)) returns a query object. There's no reason you couldn't do that and then immediately do a query-of-queries filtering on the TYPE column.

Mark Kruger reminds me that I should probably include code:

<cffunction name="DirectoryList2" returntype="query">
  <cfargument name="dirPath" type="string" required="true">
  <cfif directoryExists(arguments.dirPath)>
    <cfdirectory directory="#arguments.dirPath" name="local.DirQuery" action="LIST">
    <cfquery name="local.DirQuery" dbtype="query">
    SELECT * FROM local.DirQuery WHERE TYPE = 'dir'
    </cfquery>
    <cfreturn local.DirQuery>
  <cfelse>
    <cfthrow message="No such directory">
  </cfif>
</cffunction>
2
Mark A Kruger On

Leigh's answer is the correct one (as usual :) but I thought I'd throw in this code as a dead easy work around.

<cfdirectory directory="c:\blah" name="myDirQuery" action="LIST"/>

<Cfquery name="myDirQuery" dbtype="query">
  SELECT * FROM myDirQuery where type = 'dir'
</cfquery>

You could wrap it in your own function pretty easily. This gets you what you want in spite of the limitations of filtering.

1
ShangHugh On

I've used this in the past.

var = dirList(directory_path, false, "query")

// var is now a query record
dirArray = []; // create an array

for(i = 1;i LTE var.recordcount; i++){ 
   if(var.type[i] IS "dir") dirArray.append(var.name[i]);
}
0
SOS On

It's now possible to filter directories by name, as of CF11. That version enhanced DirectoryList() to add support for the "type" attribute. For example, to search for directory names containing "docs":

CF2018+ (using named parameters)

result = DirectoryList(path="c:\path",filter="*docs*", type="dir");

CF2016 and earlier

result = DirectoryList("c:\path", false, "query", "*docs*", "asc", "dir" );