Appearance
Working with Zip
ZipInputStream
is a type of FilterInputStream
that can directly read the contents of a zip file:
┌───────────────────┐
│ InputStream │
└───────────────────┘
▲
│
┌───────────────────┐
│ FilterInputStream │
└───────────────────┘
▲
│
┌───────────────────┐
│InflaterInputStream│
└───────────────────┘
▲
│
┌───────────────────┐
│ ZipInputStream │
└───────────────────┘
▲
│
┌───────────────────┐
│ JarInputStream │
└───────────────────┘
JarInputStream
is derived from ZipInputStream
and adds the main functionality of directly reading the MANIFEST.MF
file inside a jar file. Essentially, a jar file is a zip file with additional fixed descriptor files.
Reading a Zip File
Let’s look at the basic usage of ZipInputStream
. Typically, you create a ZipInputStream
by passing a FileInputStream
as the data source, then loop through getNextEntry()
until it returns null
, indicating the end of the zip stream.
A ZipEntry
represents a compressed file or directory. If it’s a file, you continuously read it using the read()
method until it returns -1:
java
try (ZipInputStream zip = new ZipInputStream(new FileInputStream(...))) {
ZipEntry entry = null;
while ((entry = zip.getNextEntry()) != null) {
String name = entry.getName();
if (!entry.isDirectory()) {
int n;
while ((n = zip.read()) != -1) {
...
}
}
}
}
Writing to a Zip File
ZipOutputStream
is a type of FilterOutputStream
that can directly write content to a zip file. You typically create a ZipOutputStream
by wrapping a FileOutputStream
. Before writing each file, you call putNextEntry()
, then write the byte[]
data using write()
, and call closeEntry()
to finish packaging that file.
java
try (ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(...))) {
File[] files = ...
for (File file : files) {
zip.putNextEntry(new ZipEntry(file.getName()));
zip.write(Files.readAllBytes(file.toPath()));
zip.closeEntry();
}
}
The code above does not consider the directory structure. To implement a hierarchical structure, the name
passed to new ZipEntry(name)
should use a relative path.
Summary
ZipInputStream
can read zip format streams, while ZipOutputStream
can write multiple data entries into a zip file. When combined with FileInputStream
and FileOutputStream
, you can effectively read and write zip files.