ZipInputStream
是一种FilterInputStream
,它可以直接读取zip
包的内容:
┌───────────────────┐
│ InputStream │
└───────────────────┘
▲
│
┌───────────────────┐
│ FilterInputStream │
└───────────────────┘
▲
│
┌───────────────────┐
│InflaterInputStream│
└───────────────────┘
▲
│
┌───────────────────┐
│ ZipInputStream │
└───────────────────┘
▲
│
┌───────────────────┐
│ JarInputStream │
└───────────────────┘
另一个
JarInputStream
是从ZipInputStream
派生,它增加的主要功能是直接读取jar
文件里面的MANIFEST.MF
文件。因为本质上jar
包就是zip
包,只是额外附加了一些固定的描述文件。
读取zip包
读取zip,要创建一个ZipInputStream,通常是传入一个FileInputStream作为数据源,然后,循环调用getNextEntry(),直到返回null,表示zip流结束。
一个ZipEntry表示一个压缩文件或目录,如果是压缩文件,我们就用read()方法不断读取,直到返回-1:
try (ZipInputStream zip = new ZipInputStream(new FileInputStream("C:\\Users\\computer\\Downloads\\test.zip"))) {
ZipEntry entry = null;
while ((entry = zip.getNextEntry()) != null) {
String name = entry.getName();
System.out.println(name);// 输出文件或目录名称
if (!entry.isDirectory()) {
int n;
while ((n = zip.read()) != -1) {
System.out.print((char) n);
}
}
}
}
写入zip包
- 创建一个
ZipOutputStream
,通常是包装一个FileOutputStream
- 写入一个文件前,先调用
putNextEntry()
- 用
write()
写入byte[]
数据,写入完毕后调用closeEntry()
结束这个文件的打包。
try (ZipOutputStream zip = new ZipOutputStream(new FileOutputStream("C:\\Users\\computer\\Downloads\\test.zip"))) {
File[] files = new File[]{
new File("C:\\Users\\computer\\Downloads\\mcbtcrq2-70h9c9aez8g.png"),
new File("C:\\Users\\computer\\Downloads\\image.html"),
};
for (File file : files) {
zip.putNextEntry(new ZipEntry(file.getName()));
zip.write(Files.readAllBytes(file.toPath()));
zip.closeEntry();
}
}
如果压缩包一致,会导致原压缩包中所有文件都会丢失