Java zip文件

Java對ZIP文件格式有直接支持。通過使用java.util.zip包中的以下四個類來處理ZIP文件格式:

  • ZipEntry
  • ZipInputStream
  • ZipOutputStream
  • ZipFile

ZipEntry對象表示ZIP文件格式的歸檔文件中的條目。zip條目可以是壓縮的或未壓縮的。ZipEntry類具有設置和獲取有關ZIP文件中的條目的信息的方法。ZipInputStream可以從每個條目的ZIP文件讀取數據。
ZipOutputStream可以將數據寫入每個條目的ZIP文件。ZipFile是一個從ZIP文件讀取條目的實用程序類。
以下代碼顯示如何創建ZIP文件。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Main {
  public static void main(String[] args) {
    String zipFileName = "ziptest.zip";
    String[] entries = new String[2];
    entries[0] = "test1.txt";
    entries[1] = "notes" + File.separator + "test2.txt";
    zip(zipFileName, entries);
  }

  public static void zip(String zipFileName, String[] zipEntries) {

    try (ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(
        new FileOutputStream(zipFileName)))) {

      // Set the compression level to best compression
      zos.setLevel(Deflater.BEST_COMPRESSION);

      for (int i = 0; i < zipEntries.length; i++) {
        File entryFile = new File(zipEntries[i]);
        if (!entryFile.exists()) {
          System.out.println("The entry file  " + entryFile.getAbsolutePath()
              + "  does  not  exist");
          System.out.println("Aborted   processing.");
          return;
        }
        ZipEntry ze = new ZipEntry(zipEntries[i]);
        zos.putNextEntry(ze);
        addEntryContent(zos, zipEntries[i]);
        zos.closeEntry();
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static void addEntryContent(ZipOutputStream zos, String entryFileName)
      throws IOException, FileNotFoundException {
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
        entryFileName));

    byte[] buffer = new byte[1024];
    int count = -1;
    while ((count = bis.read(buffer)) != -1) {
      zos.write(buffer, 0, count);
    }
    bis.close();
  }
}

上面的代碼生成以下結果。

The entry file  F:\website\yiibai\worksp\test1.txt  does  not  exist
Aborted   processing.

讀取Zip文件

以下代碼顯示如何讀取ZIP文件的內容。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class Main {
  public static void main(String[] args) {
    String zipFileName = "ziptest.zip";
    String unzipdirectory = "extracted";
    unzip(zipFileName, unzipdirectory);
  }

  public static void unzip(String zipFileName, String unzipdir) {
    try (ZipInputStream zis = new ZipInputStream(new BufferedInputStream(
        new FileInputStream(zipFileName)))) {

      ZipEntry entry = null;
      while ((entry = zis.getNextEntry()) != null) {
        // Extract teh entry's contents 
        extractEntryContent(zis, entry, unzipdir);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static void extractEntryContent(ZipInputStream zis, ZipEntry entry,
      String unzipdir) throws IOException, FileNotFoundException {

    String entryFileName = entry.getName();
    String entryPath = unzipdir + File.separator + entryFileName;

    createFile(entryPath);

    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(
        entryPath));

    byte[] buffer = new byte[1024];
    int count = -1;
    while ((count = zis.read(buffer)) != -1) {
      bos.write(buffer, 0, count);
    }

    bos.close();
  }

  public static void createFile(String filePath) throws IOException {
    File file = new File(filePath);
    File parent = file.getParentFile();

    if (!parent.exists()) {
      parent.mkdirs();
    }
    file.createNewFile();
  }
}

實例-2

下面的代碼顯示瞭如何使用ZipFile類。當想在ZIP文件中列出條目時,ZipFile類派上用場。

import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class Main {
  public static void main(String[] args) throws Exception {
    ZipFile zf = new ZipFile("ziptest.zip");

    // Get the enumeration for all zip entries and loop through them
    Enumeration<? extends ZipEntry> e = zf.entries();
    ZipEntry entry = null;

    while (e.hasMoreElements()) {
      entry = e.nextElement();

      // Get the input stream for the current zip entry
      InputStream is = zf.getInputStream(entry);

      /* Read data for the entry using the is object */

      // Print the name of the entry
      System.out.println(entry.getName());
    }

  }
}

以下代碼使用Stream類和lambda表達式重寫上述代碼。

import java.io.IOException;
import java.io.InputStream;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class Main {
  public static void main(String[] args) throws Exception {
    ZipFile zf = new ZipFile("ziptest.zip");

    Stream<? extends ZipEntry> entryStream = zf.stream();
    entryStream.forEach(entry -> {
      try {
        // Get the input stream for the current zip entry
        InputStream is = zf.getInputStream(entry);
        System.out.println(entry.getName());
      } catch (IOException e) {
        e.printStackTrace();
      }

    });
  }
}

GZIPInputStreamGZIPOutputStream類用於處理GZIP文件格式。