For a project I’m working on I needed to grab an existing directory and duplicate it to another location. My quick search through the Coldfusion docs didn’t return any methods that would allow me to do this. As a result, I built one that is fairly simple. It accepts two arguments: 1. directory to copy, and 2. the directory to copy to. Let’s first take a look at the function itself.
<cffunction name="duplicateDirectory" displayname="Duplicate Directory" hint="Duplicates the specifed directory in another specified directory." access="private" output="false" returntype="void">
<cfargument name="directoryToCopy" displayname="Directory To Copy" hint="The full path to the directory that is to be duplicated." type="string" required="true" />
<cfargument name="directoryToCopyTo" displayname="Directory To Copy To" hint="The full path to the directory that the duplicated directory is to be copied to." type="string" required="true" />
<cfset var loc_dirList = "" />
<cfset var loc_rootDir = listLast(arguments.directoryToCopy, "/") />
<cfset var loc_thisRootDir = arguments.directoryToCopyTo & "/" & loc_rootDir />
<cfset var loc_thisDirName = "" />
<cfset var loc_thisDirPath = "" />
<cfset var loc_thisFileName = "" />
<cfset var loc_thisFilePath = "" />
<cfset var loc_createThisDir = "" />
<cfset var loc_createThisFile = "" />
<cfset var loc_i = 0 />
<cfset var loc_dirExt = "" />
<cfset var loc_record = false />
<!--- create this root directory --->
<cfdirectory action="create" directory="#loc_thisRootDir#" />
<!--- get a list of everything in the directory to copy. **IMPORTANT: sort by 'type' and then 'directory' to ensure that all directories in the root are created before any directories
insde of those directories. After all directories have been created then the files can be copied over. --->
<cfdirectory action="list" name="loc_dirList" recurse="true" directory="#arguments.directoryToCopy#" sort="type, directory" />
<!--- loop over all directories and files --->
<cfloop query="loc_dirList">
<!--- determine if a file or directory --->
<cfif type eq "dir">
<!--- set the name and path --->
<cfset loc_thisDirName = name />
<cfset loc_thisDirPath = directory />
<cfset loc_dirExt = "" />
<cfset loc_record = false />
<!--- get the dir structure after the root dir --->
<cfloop list="#loc_thisDirPath#" delimiters="/" index="loc_i">
<cfif loc_i eq loc_rootDir>
<cfset loc_record = true />
</cfif>
<cfif loc_record eq true>
<cfset loc_dirExt = loc_dirExt & "/" & loc_i />
</cfif>
</cfloop>
<!--- set the path to create the directory --->
<cfset loc_createThisDir = arguments.directoryToCopyTo & loc_dirExt & "/" & loc_thisDirName />
<!--- create the directory --->
<cfdirectory action="create" directory="#loc_createThisDir#" />
<cfelse>
<cfset loc_thisFileName = name />
<cfset loc_thisFilePath = directory />
<cfset loc_dirExt = "" />
<cfset loc_record = false />
<!--- get the dir structure after the root dir --->
<cfloop list="#loc_thisFilePath#" delimiters="/" index="loc_i">
<cfif loc_i eq loc_rootDir>
<cfset loc_record = true />
</cfif>
<cfif loc_record eq true>
<cfset loc_dirExt = loc_dirExt & "/" & loc_i />
</cfif>
</cfloop>
<!--- set the desination path for the file to be copied to --->
<cfset loc_createThisFile = arguments.directoryToCopyTo & loc_dirExt />
<!--- copy the file to its project destination --->
<cffile action="copy" source="#loc_thisFilePath#/#loc_thisFileName#" destination="#loc_createThisFile#" />
</cfif>
</cfloop>
</cffunction>
So an example of calling this function would look something like:
<cfset variables.existingDirPath = expandPath("./") & "/templates/mytemplate" />
<cfset variables.copyDirToPath = expandPath("./") & "/duplicates" />
<cfset duplicateDirectory(variables.existingDirPath, variables.copyDirToPath) />
Also, in case you prefer using script, the same function can a be written as the following. Take your pick. **do note that most likely the cfscript version will not work on CF7MX or CF8. I believe the tag based one should work on all three versions.
component
{
public void function duplicateDirectory(required string directoryToCopy, required string directoryToCopyTo)
{
var loc_dirList = "";
var loc_rootDir = listLast(arguments.directoryToCopy, "/");
var loc_thisRootDir = arguments.directoryToCopyTo & "/" & loc_rootDir;
var loc_thisDirName = "";
var loc_thisDirPath = "";
var loc_thisFileName = "";
var loc_thisFilePath = "";
var loc_createThisDir = "";
var loc_createThisFile = "";
var loc_i = 0;
var loc_j = 0;
var loc_dirExt = "";
var loc_record = false;
var loc_fileToCopy = "";
//check if the directory exists
if(directoryExists(loc_thisRootDir))
{
//delete the directory
directoryDelete(loc_thisRootDir, true);
}
//create this root directory
directoryCreate(loc_thisRootDir);
//get a list of all directories/files in the root directory being copied
loc_dirList = directoryList(arguments.directoryToCopy, true, "query", "", "type, directory");
//loop over the query of directories and files
for(loc_i = 1; loc_i <= loc_dirList.recordcount; loc_i++)
{
//check if a directory or a file
if(loc_dirList["type"][loc_i] == "dir")
{
loc_thisDirName = loc_dirList["name"][loc_i];
loc_thisDirPath = loc_dirList["directory"][loc_i];
loc_dirExt = "";
loc_record = false;
//loop over the directory structure and get anything after the root
for(loc_j = 1; loc_j <= listLen(loc_thisDirPath, "/"); loc_j++)
{
//if the root directory has been reached
if(listGetAt(loc_thisDirPath, loc_j, "/") == loc_rootDir)
{
loc_record = true;
}
if(loc_record == true)
{
loc_dirExt = loc_dirExt & "/" & listGetAt(loc_thisDirPath, loc_j, "/");
}
}
//set path of the directory to create
loc_createThisDir = arguments.directoryToCopyTo & loc_dirExt & "/" & loc_thisDirName;
//create the directory
directoryCreate(loc_createThisDir);
}
else
{
loc_thisFileName = loc_dirList["name"][loc_i];
loc_thisFilePath = loc_dirList["directory"][loc_i];
loc_dirExt = "";
loc_record = false;
for(loc_j = 1; loc_j <= listLen(loc_thisFilePath, "/"); loc_j++)
{
if(listGetAt(loc_thisFilePath, loc_j, "/") == loc_rootDir)
{
loc_record = true;
}
if(loc_record == true)
{
loc_dirExt = loc_dirExt & "/" & listGetAt(loc_thisFilePath, loc_j, "/");
}
}
//create path of the file to create
loc_createThisFile = arguments.directoryToCopyTo & loc_dirExt;
//set the location of the file to be copied
loc_fileToCopy = loc_thisFilePath & "/" & loc_thisFileName;
//create copy the file to its new destination
fileCopy(loc_fileToCopy, loc_createThisFile);
}
}
}
}
I haven’t had a chance to test this on anything outside of my current project. So if anyone runs into any troubles using please post and I can update appropriately.
So feel free to use and adapt this as you please!