Common Lisp ZIP library

A library for .zip-file reading and writing, written in Common Lisp.

Written by David Lichteblau <>.

Send bug reports to <> (list information).

Thanks to for hosting.

Uses salza for compression, flexi-streams for external format support, trivial-gray-streams for gray streams portability, and includes for decompression.

Recent changes

2006-06-10: Fixed the gray stream port, including a data corruption bug that was in CVS for some time. (Thanks to Kevin Reid and others.) Switched to flexi-stream external-format functions for portability. Uses trivial-gray-streams now. Allegro 8.0 fix (thanks to Edi Weitz). Comment support (thanks to Surendra Singhi). CLISP workarounds (thanks to Klaus Weidner). Incompatible change: Don't bind *locale* on Allegro anymore.

2005-04-05: ACL fixes (thank to Edi Weitz). Lispworks port (thanks to Sean Ross). Store file-write-date (also fixes FilZip compatibility).


Installation (without asdf-install):

$ ln -s `pwd`/zip.asd /your/system/directory
* (asdf:operate 'asdf:load-op :zip)


Needs gray streams. Currently works out-of-the-box on SBCL, Lispworks, and ACL. Should be trivial to port to other Lisps.

Handles Unicode characters in filenames on ACL and Lispworks (within the zip-file), is waiting for someone to fix Unicode handling on SBCL.

ZIP-file reading

Zip archives are represented as opaque handles. Entries of the zip-file are named by strings and represented as objects, too.

Function OPEN-ZIPFILE (pathname) => zipfile

Open .zip-file pathname for reading and return a handle for it.

Function CLOSE-ZIPFILE (zipfile)

Close the file handle.

Macro WITH-ZIPFILE ((var pathname) &body body) => result of body

Bind var to the result of open-zipfile, evaluate body as an implicit progn and call close-zipfile before exiting.

Function GET-ZIPFILE-ENTRY (name zipfile) => zipfile-entry

Return an entry handle for the file called name.

Function ZIPFILE-ENTRIES (zipfile) => hash-table

Return a hash-table mapping filenames to entry handles for all files contained in the zip archive.

Macro DO-ZIPFILE-ENTRIES ((name-var entry-var zipfile) &body body) => nil

Map over all entries in zipfile binding name-var and entry-var to each file name and entry handle in turn. Establish implicit block named nil around the loop.

Function ZIPFILE-ENTRY-NAME (zipfile-entry) => string

Return an entry's file name as a string.

Function ZIPFILE-ENTRY-CONTENTS (entry &optional stream) => see below

If stream is given, extract entry to the (unsigned-byte 8) stream given as the argument. Otherwise, return the entry contents as an (unsigned-byte 8) vector.

Function UNZIP (pathname target-directory &key if-exists verbose) => nil

Extract all entries from the zip archive at pathname into target-directory. if-exists as for cl:open.

ZIP-file writing

zipwriters are handles used to create zip archives. They are distinct from the zip handles used for reading.

Macro WITH-OUTPUT-TO-ZIPFILE ((var pathname &key if-exists) &body body)

Function WRITE-ZIPENTRY (zipwriter name data &key file-write-date)

Append a new entry called name to zipwriter. Read data from (unsigned-byte 8) stream data until EOF and compress it into "deflate"-format. Use file-write-date as the entry's date and time. Default to (file-write-date data), use 1980-01-01T00:00 if nil.

Function ZIP (pathname source-directory &key if-exists)

Compress all files in source-directory recursively into a new zip archive at pathname. Note that entry file names will not contain the name source-directory.