# Java `ZipInputStream`教程

原文：http://zetcode.com/java/zipinputstream/

Java `ZipInputStream`教程显示了如何使用`ZipInputStream`读取 Java 中的 ZIP 文件。

## Java `ZipInputStream`

`ZipInputStream`是 Java 类，实现用于读取 ZIP 文件格式的文件的输入流过滤器。 它支持压缩和未压缩的条目。

## ZIP 

ZIP 是一种存档文件格式，支持无损数据压缩。 一个 ZIP 文件可能包含一个或多个已压缩的文件或目录。 Java Archive（JAR）建立在 ZIP 格式上。

## `ZipInputStream`构造器

`ZipInputStream`具有以下构造器：

```java
ZipInputStream(InputStream in)
ZipInputStream(InputStream in, Charset charset)

```

## `ZipInputStream getNextEntry`

`ZipInputStream`的`getNextEntry()`读取下一个 ZIP 文件条目，并将流定位在条目数据的开头。

## Java 读取 ZIP 示例

下面的示例读取一个 ZIP 文件的内容。

`JavaReadZip.java`

```java
package com.zetcode;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.time.LocalDate;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class JavaReadZip {

    private final static Long MILLS_IN_DAY = 86400000L;

    public static void main(String[] args) throws IOException {

        String fileName = "src/resources/myfile.zip";

        try (FileInputStream fis = new FileInputStream(fileName);
                BufferedInputStream bis = new BufferedInputStream(fis);
                ZipInputStream zis = new ZipInputStream(bis)) {

            ZipEntry ze;

            while ((ze = zis.getNextEntry()) != null) {

                System.out.format("File: %s Size: %d Last Modified %s %n",
                        ze.getName(), ze.getSize(),
                        LocalDate.ofEpochDay(ze.getTime() / MILLS_IN_DAY));
            }
        }
    }
}

```

该示例使用`ZipInputStream`读取给定的 ZIP 文件，并将其内容打印到终端。 我们打印文件名，文件大小和最后修改时间。

```java
String fileName = "src/resources/myfile.zip";

```

ZIP 文件位于`src/resources/`目录中。

```java
try (FileInputStream fis = new FileInputStream(fileName);

```

我们从文件创建一个`FileInputStream`。 `FileInputStream`用于读取原始字节流。

```java
BufferedInputStream bis = new BufferedInputStream(fis);

```

为了获得更好的性能，我们将`FileInputStream`传递到`BufferedInputStream`中。

```java
ZipInputStream zis = new ZipInputStream(bis)) {

```

`ZipInputStream`是从缓冲的`FileInputStream`创建的。 当资源不再需要时，`try-with-resources`将关闭流。

```java
while ((ze = zis.getNextEntry()) != null) {

```

在`while`循环中，我们使用`getNextEntry()`方法浏览 ZIP 文件的条目。 如果没有更多条目，则返回`null`。

```java
System.out.format("File: %s Size: %d Last Modified %s %n", 
        ze.getName(), ze.getSize(), 
        LocalDate.ofEpochDay(ze.getTime() / MILLS_IN_DAY));

```

`getName()`返回条目的名称，`getSize()`返回条目的未压缩大小，`getTime()`返回条目的最后修改时间。

```java
File: maven.pdf Size: 6430817 Last Modified 2017-02-23 
File: mavenbyexample.pdf Size: 1363061 Last Modified 2017-02-15 
File: modal_verbs.jpg Size: 31353 Last Modified 2017-03-04 
File: sid.jpg Size: 57708 Last Modified 2017-06-05 
File: spring-boot-reference.pdf Size: 1946586 Last Modified 2017-06-05 

```

这是一个示例输出。

## Java 解压缩 ZIP 示例

在下一个示例中，我们用 Java 解压缩 ZIP 文件。

`JavaUnzip.java`

```java
package com.zetcode;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class JavaUnzip {

    public static void main(String args[]) throws Exception {

        byte[] buffer = new byte[2048];

        Path outDir = Paths.get("src/resources/output/");
        String zipFileName = "src/resources/myfile.zip";

        try (FileInputStream fis = new FileInputStream(zipFileName);
                BufferedInputStream bis = new BufferedInputStream(fis);
                ZipInputStream stream = new ZipInputStream(bis)) {

            ZipEntry entry;
            while ((entry = stream.getNextEntry()) != null) {

                Path filePath = outDir.resolve(entry.getName());

                try (FileOutputStream fos = new FileOutputStream(filePath.toFile());
                        BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length)) {

                    int len;
                    while ((len = stream.read(buffer)) > 0) {
                        bos.write(buffer, 0, len);
                    }
                }
            }
        }
    }
}

```

该示例使用`ZipInputStream`读取给定 ZIP 文件的内容，并使用`FileOutputStream`和`BufferedOutputStream`将该内容写入目录。

```java
Path outDir = Paths.get("src/resources/output/");

```

这是我们提取 ZIP 文件内容的目录。

```java
while ((entry = stream.getNextEntry()) != null) {

```

在第一个`while`循环中，我们浏览 ZIP 文件的条目。

```java
while ((len  = stream.read(buffer)) > 0) {
    bos.write(buffer, 0, len);
}

```

在第二个`while`循环中，我们读取条目并将其写入输出流。

在本教程中，我们介绍了 Java `ZipInputStream`类。 我们创建了两个示例来读取 ZIP 文件和解压缩 ZIP 文件。 您可能也对相关教程感兴趣：[Java 读取文本文件](/articles/javareadtext/)， [Java `HashMap`教程](/java/hashmap/)， [Java `ArrayList`教程](/articles/javaarraylist/)， [Java `static`关键字](/java/statickeyword/)， [Java 中的`HashMap`迭代](/java/hashmapiterate/)， [Java8 `forEach`教程](/articles/java8foreach/)，[用 Java 读写 ICO 图像](/articles/javaico/)， [Java 教程](/lang/java/)， [用 Java 显示图像](/java/displayimage/)。