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:
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:
Launch code in new window » Download code as text file »
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:
Launch code in new window » Download code as text file »
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.
Download Code Snippet ZIP File
Comments (13) | Post Comment | Ask Ben | Permalink | Other Searches | Print Page
I am using this to zip up tif images and it works fine on the application tier, but for some reason I get the object instantation exception when I try to run it from the web tier. Any suggestions?
Posted by ahoskie on Nov 20, 2007 at 10:31 AM
@Ahoskie,
I am not sure what you mean by "Web tier". Can you explain a little more?
Posted by Ben Nadel on Nov 20, 2007 at 1:26 PM
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.
Posted by ahoskie on Nov 20, 2007 at 4:40 PM
@Ahoskie,
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.
Posted by Ben Nadel on Nov 21, 2007 at 7:44 AM
Thank you. I thought it was worth a shot if I asked.
Posted by Ahoskie on Nov 21, 2007 at 8:23 AM
What kind of modifications to the code could be made to allow pulling files from different directories?
I get a Object Instantiation Exception. error, that I think is caused by files that are expected to exist locally but don't..
Thanks.
Posted by Nick Nourie on May 2, 2008 at 1:27 PM
@Nick,
You can add any file paths you want. You just need to give it the proper Expanded path.
Posted by Ben Nadel on May 7, 2008 at 3:30 PM
When I try to run your code I get:
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 220
Called from D:\Web\MasterWebSystem\ProcurementStatus\TestUpdateMsProjDate.cfm: line 24
Called from D:\Web\MasterWebSystem\CF_Tags\Components\Corp\ZipUtility.cfc: line 220
Called from D:\Web\MasterWebSystem\ProcurementStatus\TestUpdateMsProjDate.cfm: line 24
218 : target ZIP file.
219 : --->
220 : ARGUMENTS.File
221 :
222 :
Any Idea as to why?
Posted by Bret on Jun 10, 2008 at 12:59 PM
@Bret,
Are you giving it a fully expanded file path?
Posted by Ben Nadel on Jun 10, 2008 at 1:21 PM
I am using:
<cfset objZip.AddFileEntry(ExpandPath( "D:/WebDocuments/MasterWebSystem/Acmds/CDFiles/ADL1583AS100B/CDROOT/*.*" )) />
and
<cfset objZip.Compress(ExpandPath( "D:/Web/MasterWebSystem/TemporaryFileLocation/files.zip" )) />
Posted by Bret on Jun 10, 2008 at 1:25 PM
@Bret,
You are being redundant. If you have a full path already (ex D:\....), you don't need ExpandPath() as well. In your case, take out the ExpandPath().
Posted by Ben Nadel on Jun 10, 2008 at 1:29 PM
Taking the Expandpath did not get rid of the error. So I replaced the *.* with a specific file name and then the program worked. So I assume the each file has to be named in the:
<cfset objZip.AddFileEntry( "D:/WebDocuments/MasterWebSystem/Acmds/CDFiles/ADL1583AS100B/CDROOT/*.*" ) />
<cfset objZip.AddFileEntry( "D:/WebDocuments/MasterWebSystem/Acmds/CDFiles/ADL1583AS100B/CDROOT/diststmt.txt" ) />
I was hoping a wildcard would work as I am in need of several files being zipped at once.
Posted by Bret on Jun 10, 2008 at 1:53 PM
@Bret,
Corrent, right now you need to specify all the file names.
Posted by Ben Nadel on Jun 10, 2008 at 1:55 PM