Package multiple named files using cfzip
In ColdFusion (and in Lucee too 🙂 ) you can create ZIP files easily using cfzip. The usage is simple when you want to package a single file or the whole directory, but it gets more complicated when you think of multiple named files stored in different places. So, let’s take a look at the simple “single file” and “whole directory” examples. When creating a package, you can simply use:
<!--- single file ---> <cfzip action="zip" source="/path/to/file/zipMe.txt" file="/path/to/package/packageName.zip" /> <!--- whole directory ---> <cfzip action="zip" source="/path/to/directory/" file="/path/to/package/packageName.zip" />
But what if I want to create a ZIP file containing some named files? In some cases, I let website users select what files they want to download and I’m creating the package with all of them. In this case, I can use the default behavior of the cfzip tag, which is appending. During the “zip” action, the files are simply appended to the ZIP package. So, I can do something like this:
<cfzip action="zip" source="/path/to/file/zipMe1.txt" file="/path/to/package/packageName.zip" /> <!--- initially, the packageName.zip contains one file... ---> <cfzip action="zip" source="/path/to/file/zipMe2.txt" file="/path/to/package/packageName.zip" /> <!--- and now the packageName.zip contains two files - zipMe1.txt and zipMe2.txt --->
The above method works, but the performance in such a case is poor. On each file appended to the ZIP package, the whole package is re-created. So, there is a better method – use cfzipparam:
<cfzip action="zip" file="/path/to/package/packageName.zip"> <cfzipparam source="/path/to/file/zipMe1.txt" /> <cfzipparam source="/path/to/file/zipMe2.txt" /> </cfzip>
In most cases, I’m using an array or list of files to package. In such a case, my code looks like this:
<cfset listOfFiles = "/path/to/file/zipMe1.txt,/path/to/file/zipMe2.txt,/path/to/file/zipMe3.txt" > <cfzip action="zip" file="/path/to/package/packageName.zip"> <cfloop list="#listOfFiles#" index="fileToZip"> <cfzipparam source="#fileToZip#"> </cfloop> </cfzip>
This way I can let clients chose which files to compress, the ZIP action is performant and the resulting file contains expected files.