For one of our client had requirement to download photos in zip
format and it was working file with cfzip tag. Although I have some
performance issue with cfzip tag as cfzip doesn’t allow you to zip with
list of files. We can create zip for whole folder, add single file but
can’t have ability to add list of files at single instance. In my case I
have around 50 images which I need to add into zip file and I have only
one way to do so is adding one by one file. I was looking for
alternative solution for creating zip which gives faster performance
with adding file list.
Now here is different story, recently we
have decided to move our archived photos on cloud server because of
billions of images causing disk space issue. We have two kinds of photos
in our application, one is on our file server and physically accessible
so easy to add into zip file using cfzip and other on cloud server
which give us URL to access those photos. Only way for me to add into
zip that download files from cloud and store on application server and
add into zip. I already have performance issue with cfzip for photos
stored in same server and downloading photos make it much slower.
Finally I have decided to build custom code using java zip library.
After
googling I found coldfusion code which let you create zip file using
java zip library (thanks to Artur Kordowski)which let me add files in
zip by file list but again it will not let you add file from URL. I use
cfhttp to retrieve image from cloud which return ByteArrayOutputStream
object which can be added easily into zip code component. Below is
fully functional code to add file from URL to zip component.
<cfset zipFilePath = expandPath('./test.zip') />
<cfset
images =
"http://t2.gstatic.com/images?q=tbn:_ruOuQ2EjL3wOM:http://www.flash-slideshow-maker.com/images/help_clip_image020.jpg,http://t0.gstatic.com/images?q=tbn:--IQZoA0t4jdOM:http://www.dynamicdrive.com/dynamicindex4/lightbox2/flower.jpg,http://t3.gstatic.com/images?q=tbn:7i1D2KAZcCd8yM:http://www.flash-slideshow-maker.com/images/help_clip_image004.jpg"
/>
<cfscript>
/* Create Objects */
ioOutput = CreateObject("java","java.io.FileOutputStream");
zipFile = CreateObject("java","java.util.zip.ZipFile");
zipEntry = CreateObject("java","java.util.zip.ZipEntry");
zipInput = CreateObject("java","java.util.zip.ZipInputStream");
zipOutput = CreateObject("java","java.util.zip.ZipOutputStream");
ioOutput.init(zipFilePath);
zipOutput.init(ioOutput);
zipOutput.setLevel(9);
</cfscript>
<cfloop
list="#images#" index="uri">
<cfset filename=
listlast(uri,"/") />
<cfhttp url="#uri#" method="get">
<cfset objByteIO = cfhttp.filecontent />
<cfscript>
flag = true;
path = uri;
entryFile =
filename;
// Skip if entry with the same name
already exsits
try
{
zipEntry.init(entryFile);
zipOutput.putNextEntry(zipEntry);
objByteIO.toByteArray();
zipOutput.write(objByteIO.toByteArray(), 0, objByteIO.size());
zipOutput.closeEntry();
}
catch(java.util.zip.ZipException ex)
{ skip = "yes"; }
</cfscript>
</cfloop>
<cfscript>zipOutput.close();</cfscript>
NOTE: Above code will work only when cfhttp returns ByteArrayOutputStream, in other case you may need to modify as per need.
Sep 06, 2010 12:51 PM
Jul 13, 2010 at 2:27 PM Very nice.