Here’s an ActionScript 3 based library for reading and writing zip files. I wrote this for another project I’m messing around with and thought I’d release it. I realize there’s already a useful library out there called FZip which is faster at uncompressing zip files as it uses the native uncompress method. However, it may require a script to preprocess a zip and inject Addler32 checksums which this library avoids by implementing a deflate compression decoder (inflater). If you are dealing with zips that only store files or run Python I recommend you check out FZip otherwise give this a try.
Features
- Read or write zip files
- Interface based on Java API (java.util.zip package)
Demo
The source for this demo is available here.
Documentation
Download
The zip library is available as a swc component:
nochump-ziplib-105-dist.zip
The source files and documentation are also available:
nochump-ziplib-105-src.zip
License
MIT
Usage
Below are examples of reading from a zip and writing to a new zip.
// read from a zip
import flash.utils.IDataInput;
import nochump.util.zip.*;
var loadedData:IDataInput;
// load a zip via URLStream or URLLoader using binary data format...
// create zip file
var zipFile:ZipFile = new ZipFile(loadedData);
for(var i:int = 0; i < zipFile.entries.length; i++) {
var entry:ZipEntry = zipFile.entries[i];
trace(entry.name);
// extract the entry's data from the zip
var data:ByteArray = zipFile.getInput(entry);
trace(data.toString());
}
// write to a new zip
import flash.utils.ByteArray;
import nochump.util.zip.*;
// file info
var fileName:String = "helloworld.bin";
var fileData:ByteArray = new ByteArray();
fileData.writeUTF("Hello World!");
var zipOut:ZipOutput = new ZipOutput();
// Add entry to zip
var ze:ZipEntry = new ZipEntry(fileName);
zipOut.putNextEntry(ze);
zipOut.write(fileData);
zipOut.closeEntry();
// end the zip
zipOut.finish();
// access the zip data
var zipData:ByteArray = zipOut.byteArray;
Update: April 11, 2007
Updated the library to use Apollo’s ByteArray inflate/deflate native methods when running in the Apollo environment as pointed out by Ian Thomas. The current version is 1.0.1 built with acompc from the Apollo SDK. I’ve also tested the Apollo compatible swc under a regular as3 app and everything worked fine.
Update: July 29, 2007
Supports adding a zip file comment to ZipOutput. Use ZipOutput.comment =”Your comment here”.
Update: January 28, 2008
Changed license to LGPL.
Update: November 22, 2008
Changed license to MIT.
#1 by morganusvitus on April 5, 2007 - 8:40 pm
The site looks great ! Thanks for all your help ( past, present and future !)
#2 by dchang on April 5, 2007 - 9:22 pm
Thank you!
#3 by Ian Thomas on April 9, 2007 - 3:58 pm
Hi Dave,
Just a quick note – with Apollo, you get inflate() and deflate() support for free (natively), as new methods of ByteArray.
It might be worth modifying your code to check whether the methods exist on ByteArray, then call them instead of your own if they’re present?
For example, in ZipFile.as at around line 100, you could add:
if (b1.inflate!=null)
{
b1.inflate();
return b1;
}
and you could do exactly the same in ZipOutput.
Cheers,
Ian
#4 by dchang on April 9, 2007 - 7:38 pm
Hey Ian,
That’s a great tip, I’ll definitely have to update this zip library to support it. Thanks!
#5 by Daniel Wabyick on May 23, 2007 - 3:08 pm
Hey Dave, this is a really great library. Works very well, and very quickly in Apollo.
Question though – Have you considered changing the license to use LGPL instead of GPL?
I am not a public license expert, but I believe the GPL is too restrictive to use for most commercial projects. (Thats cool if that is your intent!)
Cheers,
-D
#6 by dchang on May 23, 2007 - 4:23 pm
Thanks Daniel, well I don’t know much about public licenses myself. The reason I went with GPL was that the java source and GNU Classpath are both release under it. Though this library is not a direct port of those, I did look to them for the interface, their supported zip features, and some general ideas. So to play it safe, and out of convenience, I went with the same. However, there was an exception in GNU Classpath’s license that appears to deal with your situation. Would it help you out to add that to this library?
Anyways, I want things to be flexible for the non-commercial developer as well as the commercial. So if that exception doesn’t make it less restrictive, I’m really open to the idea of changing the license to LGPL or some other one. Lemme know
#7 by Uwe on June 5, 2007 - 7:30 pm
Hi David,
great work, thank you !
I’m using it to load a 600kb XML-File.
After “zipping” my File has only 8kb. So the start of my application is MUCH faster.
Greetings from Berlin,
Uwe
#8 by Critter on July 10, 2007 - 8:55 pm
I am attempting to use your create zip example with a slight modification
http://codeshare.ulatu.com/julff076
The zip file created is 14kb, but when I open it. the file inside is 0 bytes.
Even if I use your example as it is shown, the HelloWorld.bin file is 0 bytes.
Any suggestions would be greatly appreciated.
Critter
#9 by farid silva on July 13, 2007 - 5:36 pm
This projects sounds great. Congratulations.
Should it read a pass protected zip when providing de correct password?
It would be a way to protect data…
Thanks
#10 by dchang on July 15, 2007 - 6:14 pm
Hey Critter,
Sorry for the long delay getting back to you. Anyways I finally had the chance to look into this and the issue was in the way the entry data gets compressed under AIR…there was nothing wrong with your code. In version 1.0.1, I had tweaked it to support their native ByteArray.deflate method when building under for AIR but for some reason it doesn’t seem compatible so I’ve updated this library reverting back to a previous deflate method. Well long story short, I’ve tested this version writing zipOut.byteArray to a file within an AIR app and reading it back in with ZipFile as well as a desktop ZIP application and was successful. So please give this updated version a try and let me know if you run into any issues.
Thanks for catching this as I really have not had the chance to play with AIR.
Dave
#11 by dchang on July 15, 2007 - 6:19 pm
Hey Farid,
Thanks for your comment. I considered this but it was not a feature I needed for the project I originally wrote this library for. Plus, the steps involved for decryption seemed much when I glanced over that section in the zip spec. Would love to tie it in though if anyone wanted to contribute an implementation.
#12 by Critter on July 15, 2007 - 7:19 pm
Dave, it totally works now, thanks!!
#13 by dchang on July 16, 2007 - 8:04 am
Great to hear Critter!
#14 by Critter on July 16, 2007 - 11:31 am
Just curious mate. Is it possible to add the ability to manipulate zip file comments?
#15 by Uwe on July 26, 2007 - 8:55 am
Hi dchang,
is it possible for you to implement a feature to extract gz files ? I think the only difference to zip is the header. It would be very useful for me.
Thanks
#16 by dchang on July 26, 2007 - 5:45 pm
Comments would be easy to add, I’ll try to this weekend. As for gzip support, I’ll look into it. Hopefully it’s as easy as you say
#17 by Shakakai on July 30, 2007 - 5:42 pm
Hey dchang,
Could you post a quick example showing how to zip up multiple folders? I’m not totally sure how’d that’d work w/ the current API. Thanks in advance — Great library.
#18 by dchang on July 30, 2007 - 9:11 pm
Hey, good question…to create folders you can simply set the path with the filename when creating a ZipEntry. So with the example above…
var fileName:String = “mysubfolder/helloworld.bin”;
A directory called mysubfolder will be created with the file helloworld.bin inside when extracted.
Typically compressors will put a 0 size entry for each subfolder denoted by a trailing backslash. However, the extractors I’ve used all handled just the path/filename.ext entries alone fine unless you want to make empty folders. If you want to have directory entries anyways, this should do the trick…
var ze:ZipEntry = new ZipEntry(“mydir/”);
zipOut.putNextEntry(ze);
zipOut.closeEntry();
but again, I didn’t find this necessary and preferred less coding and a slightly smaller bytesize.
#19 by Shakakai on July 31, 2007 - 10:03 am
Awesome, thanks.
#20 by Dave on August 3, 2007 - 8:11 am
hello,
this sounds great,
i have some questions though:
-is it possible to add existing files to the (to be created) zip?
I´d like to add a file (let´s say test.jpg) that is placed in the same folder as the swf on the server to the zip. Is that possible without loading the jpg and turning it into a bytearray first?
-how does one actually save the zip data as file than if not running in apollo? do you have a php file or something to save the data on the server?
#21 by dchang on August 3, 2007 - 10:05 am
Hey there, afraid you’ll have to load the jpg into the swf via binary format but you could then use flash.display.Loader.loadBytes on that ByteArray for displaying so it only loads once. I dunno if that was your concern but without loading the jpg into swf, you might want to go with a server-side zip library.
As for saving the data to the server, I don’t have an example of this but found these links which may help… Save ByteArray to file with PHP or with AMFPHP see Send and Receive ByteArray to AMFPHP.
#22 by Chris on August 10, 2007 - 2:02 pm
Great, great, great !!!!!!!!
…you saved me a lot of time. I used your code to import contents of odf files. I thought I have to extend FZip with CRC32 algorithm feature.
Just a detail: The apollo environment settings in ZipFile.as gives an error if not using apollo!
#23 by rf on August 28, 2007 - 7:06 pm
Great job on this, David.
Here’s another vote for switching the license to LGPL or MIT. A lot of people won’t be able to use it under GPL for shareware or commercial apps because GPL requires any app using your library to also be open-source. If that’s your intention, that’s one thing but if you don’t care either way (as you imply in one of your comments) then you might want to switch to one of the other options.
#24 by Dave on October 12, 2007 - 11:43 am
hello, i asked you some things before. Sorry for my late reply, i actually didn´t get to work on the stuff for a while..
But now i did and i wanted to say thanks heaps, it works great
The way i do it now is like this:
In my app i show lots of images so i first load and show all those. Then once all are loaded the user can save a selection of them as a zip. To do this i load em again but this time as bytedata (which goes quickly as they are already in the cache) and then create a zip with subfolders using your code and then save that via php.
I´m not sure if that´s the best way to do things (i mean maybe i could get rid of the second load loop to get the images as byte data and turn the data of the already loaded images into bytedata? not sure how) but yeah, works fine
#25 by Antonos on November 23, 2007 - 6:13 am
Thank you!
great work!
#26 by Chris on December 19, 2007 - 1:23 pm
Fantastic package. Reads every zip file!
I use it to load 3D data stored in an xml file which is know zipped.
So I only need to load 28kb instead of ther original 470kb.
It’s amazing!
Well done…
#27 by Naren on January 5, 2008 - 7:07 am
Hello, Great Library……
I tried using this library…. reading a zip file works fine…
But i am not able to create a new zip file and put multiple files of different types(xml, jpg etc.)in to it and save it to the local disk….
Please help me somone who has alredy done this..
Thanks in advance….
naren
#28 by bigi on February 13, 2008 - 7:51 am
I got ‘unexpected file format’ when I want to install SWF in to Flash CS3.
Anyone had this issue?
#29 by Ostap on February 14, 2008 - 12:33 pm
Hi, great job!
FZip library doesn’t uncompress zip files with data description blocks but YOUR LIBRARY DO IT WELL.
Thanks! It was helpful for me.
#30 by Dave on March 9, 2008 - 7:11 pm
Hi Dave,
what about extracting Zip Files protected by PassWord?
Thank You!