Java Zip文件读写操作详解
OlaiolaiO 人气:0输入流(读取):
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(); } } }
加载全部内容