Copy a Directory Using CFZIP

I needed to copy a directory and all of files within it today. My first thought was that I should be able to do this in cfdirectory, but no luck there. I then hoped I could cheat and use cffile to copy a directory as though it were a file, but no luck there either. I knew that I could write some recursive code to copy the cirectory and all of its contents, but I felt there should be an easier way.

As an aside, Joe Rinehart wrote a really good directoryCopy() UDF that would have solved my problem if only I had thought to look. The lesson is to always check when trying to solve a common problem.

Anyway, I did think of a way to solve the problem without recursion by using cfzip:

Here is an implementation of directoryCopy (minus the "overwrite" argument), using cfzip:

<cffunction name="directoryCopy" output="false">
<cfargument name="source" required="true" type="string">
<cfargument name="destination" required="true" type="string">

<cfset var uid = CreateUUID()>


<cfdirectory action="create" directory="#arguments.destination#">

<cffile action="delete" file="#GetTempDirectory()">

Now that I have done this, I can't think of any advantage this has over Joe's function, but it was a fun experiment.


Here are some brief speed tests in response to Nate's query:

Test subfolders files size recursive cffile (milliseconds) cfzip (milliseconds)
Test 1 0 2 41.4K 16 16
Test 2 2 56 117K 375 94
Test 3 38 197 1.74M 235 2328
Test 4 2 56 117K 62 110
Test 5 38 197 1.74M 219 407
Test 6 115 1037 3.37M 1843 3672
Test 7 115 1037 3.37M 1046 1781

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
If you run both the UDF and the Zip on the same directory, is there a speed difference? I would assume the zip would be slower....
# Posted By Nate Miller | 3/12/08 2:14 PM

That was my assumption as well. I ran a few quick tests (posted above) that seems to bear out that assumption for the most part. Even in the only test where cfzip outperformed recursing through cffile, it failed to be faster when the same test was repeated.

So, it looks like a solution in need of a problem but it was a fun experiment.
# Posted By Steve Bryant | 3/12/08 4:15 PM
good idea with cfzip :)

today i had the same problem. appreciate your links/blog.. it helped me alot.

if you want more speed you can eliminate the recursive calls (didn't measure the exact timings but i guess it will be faster).

something link this:

<cfdirectory action="list" directory="#src#" name="q" recurse="true">
<cfloop query="q">
<cfset _dir = dest & replace(, src, '' )>
<cfif q.type eq "dir">
<cfdirectory action="create" directory="#_dir#/">
<cffile action="copy" source="" destination="#_dir#/">

you get the idea..
anyway, it's always good to avoid recursive calls :)

# Posted By duedl0r | 9/2/08 8:56 AM
How has CF not got this already! Thanks for this!
# Posted By Andy Jarrett | 7/14/10 3:05 AM
Thanks for this - an oldie but a goodie. Helped no end with mirroring Lucene index directories.
# Posted By Michael Horne | 7/25/11 5:57 AM
Hi Steve - I know this is an old post but I have re-used your code in a project that I'll be publishing on my site soon.. I'll be giving you credit in the source for the idea.

Essentially the ColdPress project allows the simple installation, co-existence and integration of ColdFusion with WordPress. I think of the amount of time I've wasted writing back-ends for projects - Stuff it - Use WordPress!!! I'll be posting details on over the next week or so.

Thanks again!

# Posted By Martin Parry | 5/4/12 8:28 PM

That sounds really interesting. I look forward to reading about it.

As to my specific solution, I think Joe Rinehart's directoryCopy() is actually the better solution. I use a modified version of that whenever I need to copy a directory.
# Posted By Steve Bryant | 5/5/12 1:39 PM
Saying that though Steve - Your method has the ability to do it across servers - Stick a couple of CFFTP commands in between!

Will keep you advised about ColdPress - The joys of work - never get chance to finish your own bits!
# Posted By Martin Parry | 5/10/12 6:33 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.