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 cflib.org 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:
<cfargument name="source" required="true" type="string">
<cfargument name="destination" required="true" type="string">
<cfset var uid = CreateUUID()>
<cfzip
action="zip"
file="#GetTempDirectory()##uid#.zip"
recurse="yes"
source="#arguments.source#"
storePath="yes"
/>
<cfdirectory action="create" directory="#arguments.destination#">
<cfzip
action="unzip"
file="#GetTempDirectory()##uid#.zip"
destination="#arguments.destination#"
storePath="yes"
/>
<cffile action="delete" file="#GetTempDirectory()##uid#.zip">
</cffunction>
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.
Update
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 |
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.
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( q.directory, src, '' )>
<cfif q.type eq "dir">
<cfdirectory action="create" directory="#_dir#/#q.name#">
<cfelse>
<cffile action="copy" source="#q.directory#/#q.name#" destination="#_dir#/#q.name#">
</cfif>
</cfloop>
you get the idea..
anyway, it's always good to avoid recursive calls :)
cheers
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 http://www.coldfusion.com.au/blog/ over the next week or so.
Thanks again!
Martin
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.
Will keep you advised about ColdPress - The joys of work - never get chance to finish your own bits!