FZip Alpha Release: Create And Modify ZIP Archives

FZip has been around for some time now, and people seem to like it. However one feature has been asked for repeatedly: In addition to reading ZIP archive, people want to be able to create new (and modify existing) archives.

So i finally sat down this weekend and added that.

The code is not tested very well (it works for me but may not work for you) and has no ASDocs yet, so i release it as an alpha version, with the hope of massive bug feedback.. :)

Download: fzip_1_0_52_alpha.zip fzip.zip

New methods in class FZip:

  • addFile(name:String, date:Date, content:ByteArray)
  • addFileAt(index:uint, name:String, date:Date, content:ByteArray)
  • removeFileAt(index:uint)
  • serialize(stream:IDataOutput)

Sample code:

// Create file contents
var ba:ByteArray = new ByteArray();
ba.writeUTFBytes("Hello World!");
// Create ZIP archive and add file
var zip:FZip = new FZip();
zip.addFile("hello.txt", null, ba);
// Serialize ZIP into a new file
// (we use the Adobe AIR specific class FileStream here,
// but you can as well use ByteArray or anything that
// implements IDataOutput)
var file:File = File.applicationStorageDirectory;
file = file.resolvePath("hello.zip");
var stream:FileStream = new FileStream();
stream.open(file, FileMode.WRITE);
zip.serialize(stream);
stream.close();

28 thoughts on “FZip Alpha Release: Create And Modify ZIP Archives

  1. This is such a great utility, thanks so much you guys. Really revolutionary stuff.

    Something that was pretty confusing was that the CompressionAlgorithm class seems to only be included in the AIR framework. I’m not sure why it’s in the flash.utils directory but not shipped with my installation of FlashCS3, Flex2, or Flex3. Also, the input for ByteArray.uncompress is different in AIR than the one shipped with the other products.

    I thought I’d mention this since I didn’t see it in any of your posts, or even in the official docs… It might be nice if you clued people in that AIR is a requirement if that’s the case, or perhaps there’s some update to the CS3/Flex3 frameworks that I don’t know about, but that too would be nice to mention…

    Anyway thank again, great work, this is an invaluable tool I can use right away on all of my current projects! :)

  2. Thanks, those previous errors are gone now in the code. Your sample code above more or less works, once you change the smart quotes back to regular quotes and remove the parameter null from the line, zip.addFile(“hello.txt”, null, ba), which only accepts 2 parameters in your 1.0.055 version.

    I’m really chomping at the bit here, I can use this utility immediately as soon as it’s possible for me to create a zip file that works with it in any way! A standard OSX zip file gives the error, “Data descriptors are not supported” when you try to load it with FZip. I have no idea how to run a Python script by the way if that’s mandatory.

    Your code above does create a hello.txt file (awesome!), although I had to hunt to discover that it was saved in an obscure library subfolder. I assume that the next step would be to figure out some way to load in the files I want to add to the zip, serialize them into ByteArrays, so back to the books. That sounds like an app unto itself… am I supposed to program that?

    Anyway, if anyone could make this process just a tiny bit easier, or help me figure out how I can create an FZip-compatible ZIP from any set of existing files, in any way shape or form on OSX, I can put this thing to use right away!

    Thanks again and sorry to need hand-holding.

  3. This looks amazing! Someone should send it to the Papervision 3d, because unless they’ve changed things, a few months ago they were loading 3ds max models straight in from files that could seriously use compression!!!

    Keep it up!

  4. @Moses:

    Yes the new API extensions changed a bit as you noticed (the blog post is a bit out of sync here). The 1.0.055 archive contains ASDocs which are up to date though.

    As for the loading files, serializing into ByteArray, feeding that to FZip and writing out the generated ZIP file, yes, you are supposed to program that. :) Maybe i put together some better code examples for the release that illustrate the whole process.

    Concerning your data descriptor problem: FZip does not support ZIP files that contain data descriptors. This is a technical problem that lies buried deep down in the PKZip file format and the Flash APIs: In a nutshell, data descriptors are located at the end of a ZIP archive and contain the sizes of the contained files (it’s like a directory). FZip needs to know the size of contained files before parsing the corresponding entry though, so it can’t parse those kind of ZIP archives (and unfortunately the Python script doesn’t fix that). In a ZIP archive that does not contain data descriptors the size info is contained in the regular file entries, just the way FZip needs it.

    I am on Windows so i don’t really know what zip tools are available on Macs. All Windows zip tools i tested write archive without data descriptors. I also know of Mac users who successfully used FZip in the past, so you might want to check out some other zip tool if possible?

    Somebody should write a zip tool (based on FZip) in AIR one day.. ;)

    @Martin:

    Thanks! I am almost 100% positive that the Papervision 3D guys know of FZip and its benefits. I am not too familiar with the code base so i can’t really say if it makes sense to integrate FZip into PV3D. I have already seen PV3D demos that use FZip, btw.

  5. Okay so, for anyone who wants to use FZip on the Mac, here’s how I finally got it to work:

    1. Setup: For the sake of this example, put a copy of the python fixer tool (included in FZip under tools) on your Desktop, along with a folder of files you want to zip up. Open Terminal. I’m not a command line guy myself so maybe there are better ways to do the next steps but they worked for me. (Terminal is in Applications/Utilities). Type in the word zip and hit return, this shows the list of options for zipping files. Finally, download and install Python, it’s a simple, normal installation with no catches.

    2. In Terminal, navigate to your desktop, like: cd /Users/moses/Desktop

    3. Create the zip directory, using this syntax but replace the names with whatever you want to call the zip and whatever the folder of files to zip is actually called: zip newZipFile.zip folderOfFiles/*

    (For a plain folder of files this is fine. There’s also an option -j that lets you exclude folders, and some other options for including subfolders recursively. FZip doesn’t mind folders, foldernames are readable in your code via a file’s filename property.)

    4. Check your Desktop to see if the zip is there, and try unzipping it to see if the files are in it. Last, apply the adler checksum fix which we copied to the desktop in step1, using the actual name of your zipfile of course: python fzip-prepare.py newZipFile.zip

    (You may see a warning about a deprecated something or other when you run the fix, which is okay.)

    Hope that helps someone out.

  6. Hi Claus, and happy new year –

    I’m running into a gnarly FZip issue: Zip files do not seem to cache in browsers!

    This means that users have to wait for the same image series to download multiple times. We need to find a fix for this or FZip won’t be viable for our project.

    I’ve tried changing the extension to .jpg and .html, as well as removing the extension, to trick the browser into caching the files… none of these tricks seem to work. Is there some way we could manipulate the file header to force browser-caching?

    (By the way, on Mac Safari browser, the activity window shows an error every time I load an FZip file, unfortunately I can’t read the entire thing because that window’s view controls are locked, it reads “Operation Could Not Be Completed (WebKitErrorDo…” then gets truncated by the window. Not sure if it’s this failure to complete the load that is causing the lack of caching perhaps.)

  7. Hi Moses, happy new year to you too!

    Unfortunately i don’t know how to help you with caching and that Safari error.. here, caching ZIPs works like a charm. I woudn’t know why this would fail, as we’re using URLStream to load ZIPs and caching should be enabled by default. Also if you look at the demo on the FZip homepage, the browser caches the file (at least here on Windows). Maybe it’s some setting on your server that prevents caching, or an issue with Flash and Safari?

  8. thanks for the reply… i did not realize that trying to get this stuff to work on mac would be such a chore, i’ve spent hours on it and thought i finally had it working.

    it doesn’t cache in either safari or firefox and it’s not the server, everything else caches fine. i am using the step by step process of zipping the files then injecting the checksum using the mac command line. i’m sure it’s just some issue with the mac’s zip.

    i really wish you guys had access to a mac to look at this stuff, i don’t have a pc but it you are going to drive me to buy Windows just to get your utility to work.

  9. hi all……..
    i am new at flash so i am not getting how to use this ……..
    where should i put the fzip folder for using……

  10. I just want to say that this is a fantastic bit of kit, especially when combined with air.

    simply awesome

  11. I am getting some confusion regarding zip file modification.
    Problem is that when I reload the created zip file and modify data and decompress it, it show me CRC failed.

    One technique as I got that create a new zip, copy and merge all old and new files and replace the older zip.

    Is there any specific technique to handle the situation?

  12. I am using your library to extract a zip file created with WinZip. The zip file is created with winzip 9.0 with normal compression. I then ran the zip file through your python script which only outp uts the following:

    sys:1: DeprecationWarning: struct integer overflow masking is deprecated

    The zip file is modified however so I assume that it worked. Once I run my AS3 program and use FZip to extract the zip file I get the following error below. Any assistance appreciated.

    FZip.as line 514
    Adler32 checksum not found
    at deng.fzip::FZipFile/parseContent()[C:\Projects\fzip\trunk\src\deng\fzip\FZipFile.as:514]
    at deng.fzip::FZipFile/parseFileContent()[C:\Projects\fzip\trunk\src\deng\fzip\FZipFile.as:413]
    at deng.fzip::FZipFile/parse()[C:\Projects\fzip\trunk\src\deng\fzip\FZipFile.as:362]
    at deng.fzip::FZip/parseLocalfile()[C:\Projects\fzip\trunk\src\deng\fzip\FZip.as:431]
    at deng.fzip::FZip/parse()[C:\Projects\fzip\trunk\src\deng\fzip\FZip.as:392]
    at deng.fzip::FZip/loadBytes()[C:\Projects\fzip\trunk\src\deng\fzip\FZip.as:179]

  13. hi

    your library is very cool. thank you!

    i have one question:
    how is it possible to extract an empty folder?

    i’m not able to do that. When the folder contains files it works and the folder is here.

    thank you very much

  14. Hii even i have the same issue has Vishal has,can anyone gimme a idea how can i zip a whole folder

  15. I am working with OSX. Is there any way to maintain the file permissions? If I extract a file using the OS or any tools the file permissions are maintained. In this case it’s an executable file. When I use this lib, the permissions are lost when I decompress. I used this tool to create the zip file to make sure it’s zipped properly. I am working with Flex Builder 3 building an adobe air app.

  16. Vishal & Mitesh:

    Turned out zipping folders was pretty straight forward :)

    To place a file inside a folder in the zip file, just specify the foldername followed by “/” before the filename..:

    zip.addFile(“MyFolder/” + inpFile.name, bArray);

    Claus: Great work!! You saved my day!

  17. Great library! This is enormously useful. Thank you!

    Here’s a couple of things that I found confusing, hopefully the solutions that I found can help someone else.

    1. How do you determine if the checksum has been properly embedded?
    Install Python somewhere on your computer, navigate to the directory. Drag the zipped file that you want to use and the fzip-prepare.py script into the python directory. Right click fzip-prepare.py and select “edit with IDLE”. Run the console. Type these two lines:
    import os
    os.system(“python fzip-prepare.py yourZip.zip”)
    If the console returns 0, you’ve successfully added the checksum, any other number indicates some failure.

    2. What should the directory structure inside the zip look like for fZip to work?
    When you download the icons, the demo source code expects the zipped file to be the ‘icons’ directory. To have the code immediately work either select the ‘icons’ subdirectory and zip/embed the checksum into that. Or, edit the path to the icons in provided demo source code.

  18. Nice library.

    I’m having one issue that I haven’t been able to overcome. I’m creating a zip file using your library. The resulting zip appears fine and can be opened with 7zip or through Windows with no problem. However, I’m trying to read the file with python (2.5) and am getting a BadZipFile exception.

    The curious thing is that this error occurs with your library or the nochump library…which leads me to wonder if its an issue either with python or the underlying compress method in flex.

    Any thoughts? Thanks.

  19. Hi,

    I’m finding that if I create a zip with FZIP, save it, then attempt to open it with FZIP, I get the following error:

    Unknown Record Signature

    The signature in question is this: 1196314761 [0x474e5089].

    I’m really confused – is there something I’m missing?

    I’m using AIR 3.2, for both the creation and the reading of the zip…

    Cheers

  20. Hi,

    I am working on an as3 project where I need to somehow gain access to the data held in thousands of .png files. Embedding each one individually would not make sense, so after searching for the longest time, I found FZip, which seems to be what I’m looking for. Having zero understanding of what a checksum is I am not able to get FZip working for me. I would greatly appreciate extremely detailed (as detailed as possible) step by step processes of how to:
    1. Set up the .zip file so that when it is loaded the .getFileCount() does not return zero.
    2. apply the adler32 checksum to my zip file using python. What version of python, where do I put the script and the .zip, what do i click, how do I know if it has worked? (Note that I have zero knowledge about python so any terms for that you use will not make any sense to me.)

    thank you to whoever answers!

  21. NOOB,

    You want version 2.4 of python. Once installed, go to Computer>Python24.
    There you put “fzip-prepare.py” and “yourZip.zip” assuming that the name of
    your zip file is “yourZip”.
    In the start menu, search for Python (command line)
    Open it and type:”
    import os
    os.system(“python fzip-prepare.py yourZip.zip”)

    if it returns zero, the adler32 checksum has been injected. Now when you try and
    read in the files from the .zip in your project, try something like this:
    Let’s assume you are in the Main class.

    private var zip:FZip = new Fzip();

    public function Main():void {
    zip.addEventListener(Event.COMPLETE, onComp);
    zip.load(new URLRequest(“yourZip.zip”));
    }
    private function onComp(evt:Event):void {
    trace(String(zip.getFileCount()));
    }
    //You will see the number of files in your zip traced to the logger.

Comments are closed.