Java Zip文件读写操作详解
输入流(读取):
ZipInputStream是一种FileInputStream流,它可以直接读取Zip压缩包的内容:
┌───────────────────┐
│ InputStream │
└───────────────────┘
▲
│
┌───────────────────┐
│ FilterInputStream │
└───────────────────┘
▲
│
┌───────────────────┐
│InflaterInputStream│
└───────────────────┘
▲
│
┌───────────────────┐
│ ZipInputStream │
└───────────────────┘
▲
│
┌───────────────────┐
│ JarInputStream │
└───────────────────┘
另一个JarInputstream是从ZipInputStream派生出来的,它增加的主要功能是直接读取jar文件里面的MANIFEST.MF文件。因为本质上jar包就是zip包,只是额外增加了一些固定的描述文件。
根据上述继承关系,最终还是回到了Inputstream这个抽象类中。而Java的IO标准库使用Decorator装饰器模式为Inputstream和OutputStream增加功能:
可以把一个Inputstream和任意一个FilterInputStream组合。
可以把一个OutputStream和任意一个FilterOutputStream组合。
通过装饰器模式也就可以使用ZipInputStream来操作ZIP文件了。
ZipInputstream的基本用法是:
创建一个ZipInputstream对象,传入一个FileInputstream作为数据源,然后调用getNextEntry()方法,直到返回值为null,表示zip流结束。
一个ZipEntry表示一个压缩文件或目录,如果是压缩文件,我们就用read()方法不断读取,直到返回-1:
import java.io.FileInputStream; import java.io.IOException; import java.nio.charset.Charset; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class Demo02 { public static void main(String[] args) { try (ZipInputStream zip = new ZipInputStream(new FileInputStream("d:\\IOTest\\1-201023201325.zip"), Charset.forName("gbk"))) { ZipEntry entry = null; // 获取压缩文件中的每个子文件 while ((entry = zip.getNextEntry()) != null) { System.out.println(entry.getName()); } } catch (IOException e) { e.printStackTrace(); } } }
输出流(写入):
也称为压缩流,它用于以zip格式写入文件,也就是把文件打包成压缩文件,常用于附件下载,文件压缩存储。
┌───────────────────┐
│ OutputStream │
└───────────────────┘
▲
│
┌───────────────────┐
│ FilterInputStream │
└───────────────────┘
▲
│
┌────────────────────┐
│DeflaterOutputStream│
└────────────────────┘
▲
│
┌───────────────────┐
│ ZipInputStream │
└───────────────────┘
▲
│
┌───────────────────┐
│ JarOutputStream │
└───────────────────┘
压缩流常用的两个方法为:
1.
// 开始写入新的 ZIP 文件条目并将流定位到条目数据的开头。如果仍处于活动状态,则关闭当前条目。 // 这里的ZipEntry就是一个条目 // 条目类:ZipEntry(表示 ZIP 文件条目) public void putNextEntry(ZipEntry e) throws IOException {}
2.
// 关闭当前 ZIP 条目并定位流以写入下一个条目 public void closeEntry() throws IOException {}
ZipOutputStream可以把多份数据写入zip包
先创建一个ZipOutputStream对象,从中包装一个FileOutputStream流,然后每写入一个文件(条目类),先调用putNextEntry(),然后write()写入byte[]数据,写入完毕后调用closeEntry()方法结束这个文件的打包。
具体实现代码如下:
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * 将指定文件写入zip文件 */ public class Demo02 { public static void main(String[] args) { // 原始目录 File rootDir = new File("d:\\IOTest\\tuji"); // 将原始目录中的文件,“写入”zip压缩文件 try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(rootDir.getParent() + "\\" + rootDir.getName() + ".zip"))) { // 获取并遍历原始目录下的子文件列表 File[] files = rootDir.listFiles(); // 循环写入每一个文件 for (File f : files) { // 创建一个ZipEntry out.putNextEntry(new ZipEntry(f.getName())); // 将源文件的字节内容,写入zip压缩包 out.write(Files.readAllBytes(f.toPath())); // 结束当前zipEntry out.closeEntry(); } } catch (IOException e) { e.printStackTrace(); } } }
到此这篇关于Java Zip文件读写操作详解的文章就介绍到这了,更多相关Java Zip文件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!