<cfzip> handles ZIP and JAR archives directly: compressing a directory into a ZIP, extracting one back out, listing what's inside without extracting anything, and reading a single entry's contents (as text or binary) on its own.
Learning Objectives
After completing this lesson, you'll be able to:
- Create a ZIP archive from a directory, and extract one back out.
- List an archive's contents and read the result's columns, without extracting anything.
- Read a single entry's contents directly, as text or binary, and filter which entries an operation actually touches.
How cfzip Fits In
Source Directory
cfzip action="zip"
ZIP / JAR File
The Reverse Direction: Extracting an Archive
ZIP / JAR File
cfzip action="unzip"
Destination Directory
Creating an Archive
<cfzip action="zip" file="#expandPath('./exports/backup.zip')#" source="#expandPath('./data')#" overwrite="true">cfzip(
action = "zip",
file = expandPath("./exports/backup.zip"),
source = expandPath("./data"),
overwrite = true
);cfzip does not create directories for you, the destination folder for the ZIP file itself must already exist. Only the archive is created, not its parent path.
Extracting an Archive, With a Filter
<cfzip action="unzip" file="#expandPath('./exports/tools.jar')#"
filter="*.class" destination="#expandPath('./extracted')#">cfzip(
action = "unzip",
file = expandPath("./exports/tools.jar"),
filter = "*.class",
destination = expandPath("./extracted")
);filter accepts multiple patterns separated by a pipe (e.g. "*.jpg|*.png"), matching cfdirectory's own filter syntax.
Listing an Archive's Contents
ZIP / JAR File
cfzip action="list"
Query of Entries
<cfzip action="list" file="#expandPath('./exports/backup.zip')#" name="entries">
<cfoutput query="entries">
#entries.name# — #entries.size# bytes (#entries.type#)<br>
</cfoutput>The List Query's Columns
| Column | Meaning |
|---|---|
| name | The entry's filename, without its containing directory |
| directory | The path within the archive containing this entry |
| size | Uncompressed size, in bytes |
| compressedSize | Actual compressed size, in bytes |
| type | "directory" or "file" |
| dateLastModified | The entry's last-modified timestamp |
| comment | Any comment metadata stored with the entry |
| crc | CRC-32 checksum, for verifying the entry's integrity |
Reading a Single Entry Directly
read pulls one entry's contents into a variable as text; readBinary does the same for binary content like an image, without ever extracting the file to disk.
<cfzip action="read" file="#expandPath('./exports/backup.zip')#"
entrypath="notes/readme.txt" variable="readmeText"><cfzip action="readBinary" file="#expandPath('./exports/backup.zip')#"
entrypath="images/logo.jpg" variable="logoBytes">The action Attribute: Full Reference
| action | What it does |
|---|---|
| zip (default) | Creates or updates a ZIP/JAR file from a source directory |
| unzip | Extracts an archive's contents to a destination directory |
| list | Returns a query describing the archive's contents, without extracting anything |
| read | Reads one entry's contents as text into a variable |
| readBinary | Reads one entry's contents as binary into a variable |
| delete | Removes one or more entries from an existing archive |
Lucee-Specific Extensions Worth Knowing
| Attribute | What it adds |
|---|---|
| encryptionAlgorithm | "standard", "AES-128", or "AES-256" for password-protected archives, Adobe ColdFusion supports encryption too, but with fewer algorithm choices |
| compressionMethod | Choose a deflate variant, or "store" to add files with no compression at all |
| filterDelimiters | Changes the character used to separate multiple filter patterns, the pipe (|) by default |
| filter as a closure | Accepts a function that receives each entry and returns true/false, instead of only a wildcard pattern string |
As of Lucee 7.1, zip functionality moved out of Lucee's core into the separate Compress extension, confirm it's installed if cfzip stops working after an upgrade.
Common Beginner Mistakes
Assuming cfzip will create a missing destination folder
It won't, for either the ZIP file's own location or an unzip destination. The containing directory must already exist beforehand.
Extracting an entire large archive just to read one file
action="read" or "readBinary" pulls a single entry's contents directly, with entryPath, no full extraction needed.
Assuming a password alone fully secures an archive without checking the algorithm
Setting only a password with no explicit encryptionAlgorithm defaults to AES-256 on engines that support it, but confirm this, don't assume it, especially across different CFML engines.
Forgetting that filter uses a pipe to separate multiple patterns
A filter like "*.jpg,*.png" won't work as expected, the separator is a pipe: "*.jpg|*.png".
Best Practices
- Ensure the destination directory exists before calling zip or unzip, cfzip will not create it.
- Use list to inspect an archive's contents before extracting, especially for a ZIP file from an untrusted source.
- Read a single known entry directly with read/readBinary rather than extracting an entire archive when only one file is actually needed.
- Set encryptionAlgorithm explicitly when a password is used, rather than relying on a default that can differ by engine.
Interview Questions
What's the default action for cfzip if none is specified?
zip, creating or updating an archive from a source directory.
How do you read a single file's contents out of a ZIP archive without extracting the whole thing?
Use action="read" (for text) or action="readBinary" (for binary content) with entryPath set to that specific entry's path inside the archive.
Does cfzip create missing directories for you?
No. Neither the ZIP file's containing folder nor an unzip destination is created automatically, both must already exist.
What does the list action return, and what are two of its columns?
A query describing the archive's contents without extracting anything, columns include name, size, compressedSize, type (file or directory), and crc, among others.
Name a cfzip attribute available in Lucee but not standard across CFML engines.
compressionMethod (choosing a deflate variant, or no compression at all via "store") is a Lucee-specific extension.
Summary
In this lesson, you created and extracted ZIP archives with cfzip, listed an archive's contents and read the result query's columns, read a single entry's contents directly as text or binary, filtered which entries an operation touches, and covered real Lucee-only extensions (encryptionAlgorithm, compressionMethod, closure-based filtering) beyond the standard CFML feature set.
What's Next?
The next lesson covers cfexecute, running an external program or system command directly from CFML.