Zipping All Code Snippets With ColdFusion Zip Utility Component

Yesterday, Boyan Kostadinov suggested that I provide a way to zip all the code snippets for a given blog entry and provide it for easier download. I thought this was brilliant, and is only one of several great recommendations that Boyan has given to me (thanks dude!). ColdFusion 8 (Scorpio) is going to provide awesome Zip functionality but until then, I have to roll my own zip functionality.

But, when thinking about the zipping features I wanted, I have to remember what I am doing - I have to remember what the context is. Most zipping functionality that I have come across deals with file or directory entries. That is good, but it is not really useful for my scenario. I am going to be taking chunks of textual data out of my blog entry and zipping those together. Now, I could write each code snippet to its own text file and then zip all those text files together, but that seems unnecessary.

What I really want to be able to do is grab the text of the code snippets and add those directly to the resultant zip archive file. It's not done yet, but I am on my way. What I have created is a very simple ColdFusion Zip Utility that can have entries added to it in three different way:

File path entries in which you just add system file paths.

Text entries in which you can add a chunk of text and give it a file name.

Byte array entries in which you can add binary data directly to the zip file and give it a name.

I figure this will give me the flexibility that I need to handle the code snippet zipping. Here is a demo of how it can be used:

<!--- Create an instance of the Zip utility. --->

<cfset objZip = CreateObject( "component", "ZipUtility" ).Init() />

<!---

Zip entries can be added as file paths. This

is pretty starndard. Here we can add N file

path arguments.

--->

<cfset objZip.AddFileEntry(

ExpandPath( "./data/file_a.jpg" ),

ExpandPath( "./data/file_c.jpg" )

) />

<!---

Zip entries can be also be added as actual text

entries that will be stored as text files.

--->

<cfset objZip.AddTextEntry(

Text = "This is a text file.",

Name = "text_entry.txt"

) />

<!---

In addition to text data, we can also add binary

data directly to the zip file. In this demo, we are

going to read in the image binary and then add it

as a zip entry.

--->

<cffile

action="READBINARY"

file="#ExpandPath( './data/file_b.jpg' )#"

variable="binFileData"

/>

<!--- Add binary image data directly to zip file. --->

<cfset objZip.AddByteEntry(

ByteArray = binFileData,

Name = "file_b.jpg"

) />

<!---

ASSERT: At this point, we have defined what files,

text and binary data is going to end up in the Zip

file. The Zip file has NOT yet been written.

--->

<!--- Compress this zip file. This will write the file. --->

<cfset objZip.Compress(

ExpandPath( "./files.zip" )

) />

Notice that in the above code, the text and the image binary are added directly to the zip (not written to intermediary files). Running the code above produces the zip archive file, files.zip. If I open that file (as well as the resultant text entry and the resultant byte array entry to prove that it worked), we get the following:

Notice that the text entry translated perfectly into our text_entry.txt and our byte array entry translated perfectly into out file_b.jpg.

Here is the code for the ZipUtility.cfc ColdFusion component that makes creating zip archives with ColdFusion possible through the magic which is Java:

Now, some notes of caution: Adding the file path entries is a no brainer. Those get read and zipped at the time of compression so that they do not have any memory overhead issues. Adding the text and byte array entries is another beast altogether; these entries get stored in the private scope of the ZipUtility.cfc ColdFusion component. That means that all text and byte array entry data gets stored in the RAM of the computer. This can be a problem is you go nuts and start zipping HUGE text files and binary objects in this manner.

That is not what that was intended for. In my use case, I will be zipping very small code snippets - several hundred lines MAX! This will not put the server in harm's way.

Also, for ease of use, I am storing all files in a single directory. I am sure this would cause problems for most people, but for now, for this scenario, it works quite nicely. More to come on this topic later.

the application on apache and when you run the code from apache the zip function errors out, put when I run it on the application server everything works fine. I was just wondering if this was a common issue or not.

It might be?? To be quite honest, I am not that familiar with Apache. I just know about things when I run them in ColdFusion. I know ColdFusion sits on top of a web service like Apache or IIS, but I am not sure how to do anything outside of ColdFusion.

An exception occurred when instantiating a Java object. The class must not be an interface or an abstract class. Error: ''.

The error occurred in D:\Web\MasterWebSystem\CF_Tags\Components\Corp\ZipUtility.cfc: line 220Called from D:\Web\MasterWebSystem\ProcurementStatus\TestUpdateMsProjDate.cfm: line 24Called from D:\Web\MasterWebSystem\CF_Tags\Components\Corp\ZipUtility.cfc: line 220Called from D:\Web\MasterWebSystem\ProcurementStatus\TestUpdateMsProjDate.cfm: line 24

I trying to use your code to zip some files(data) from a form that takes customer details and them email them to our client - This seems to work fine but I would like to password protect them. Any ideas?

I am the co-founder and lead engineer at InVision App, Inc — the world's leading prototyping,
collaboration & workflow platform. I also rock out in JavaScript and ColdFusion 24x7 and I dream about
promise resolving asynchronously.