亲宝软件园·资讯

展开

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();
        }
    }
}

加载全部内容

相关教程
猜你喜欢
用户评论