【Java】ZIP 処理 ~圧縮編~

■ サンプル

ZipHelper.java

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipHelper {
   public static void zip(String zipFile, String... inputFilePathes) {
      try (ZipOutputStream zipOutputStream = new ZipOutputStream(
            new FileOutputStream(zipFile))) {
         for (String inputFilePath : inputFilePathes) {
            File file = new File(inputFilePath);
            ZipHelper.zip(zipOutputStream, file, file);
         }
      } catch (Exception ex) {
         ex.printStackTrace();
      }
   }

   private static void zip(ZipOutputStream zipOutputStream, File rootFile,
         File targetFile) {
      if (targetFile.isDirectory()) {
         // Directory
         File[] files = targetFile.listFiles();
         for (File file : files) {
            ZipHelper.zip(zipOutputStream, rootFile, file);
         }
      } else {
         // File
         String zipEntryPath = ZipHelper.getZipEntryPath(rootFile, targetFile);
         ZipEntry zipEntry = new ZipEntry(zipEntryPath);
         try (BufferedInputStream inputStream = new BufferedInputStream(
               new FileInputStream(targetFile))) {
            zipOutputStream.putNextEntry(zipEntry);
            
            ZipHelper.writeStream(inputStream, zipOutputStream);
            
            zipOutputStream.closeEntry();
         } catch (FileNotFoundException ex) {
            ex.printStackTrace();
         } catch (IOException ex) {
            ex.printStackTrace();
         }
      }
   }

   private static String getZipEntryPath(File rootFile, File targetFile) {
      int lengthToExtractZipPath = rootFile.getPath().length()
            - rootFile.getName().length();
      return targetFile.getPath().replace("\\\\", "/")
            .substring(lengthToExtractZipPath);
   }

   private static void writeStream(
         InputStream inputStream, OutputStream outputStream)
         throws IOException {
      int availableByteNumber;
      while ((availableByteNumber = inputStream.available()) > 0) {
         byte[] buffers = new byte[availableByteNumber];
         int readByteNumber = inputStream.read(buffers);
         if (readByteNumber < 0) {
            break;
         }
         outputStream.write(buffers, 0, readByteNumber);
      }
   }
}

Main.java

* 使用者
* C:\\tempに「Sample.zip」ができる
public class Main {
   public static void main(String[] args) {
      ZipHelper.zip(
            "C:\\temp\\Sample.zip",
            "C:\\temp\\2014-06-04",
            "C:\\temp\\2014-06-05",
            "C:\\temp\\2014-06-06\\2014-06-06.log");
   }
}

補足

 * フォルダを複数指定しても纏めてZip化してくれる

■ 使用上の注意

 * パスワード付ZIPファイルは、2018/01/24現状、標準JavaAPIではできない
https://bugs.java.com/view_bug.do?bug_id=6502004
  => Zip4j を使用する。以下の関連記事を参照のこと。
https://blogs.yahoo.co.jp/dk521123/37357284.html


関連記事

Java

ZIP 処理 ~圧縮編~
http://blogs.yahoo.co.jp/dk521123/33497835.html
ZIP 処理 ~解凍編~
http://blogs.yahoo.co.jp/dk521123/33645352.html
ZIP 処理 ~パスワード付ZIPファイル / Zip4j 編~
https://blogs.yahoo.co.jp/dk521123/37357284.html
''' 【Servlet】 ZIP圧縮と同時にファイルをダウンロードさせる ===
http://blogs.yahoo.co.jp/dk521123/33647497.html

C#

ZIP圧縮・解凍に関するサンプルプログラム
http://blogs.yahoo.co.jp/dk521123/20127299.html
C#でZIPに圧縮・解凍について
http://blogs.yahoo.co.jp/dk521123/20103286.html