概要

JavaにはZipファイルを作ったり読み込んだりするクラスが標準で備わっています。ZipEntryとZipOutputStreamを使えばZipファイルを作成できるので早速ソースコードを見てみましょう。最初のサンプルではファイルを1だけ格納したZipファイルを作ります。

ソースコード

import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import java.nio.file.Files;
import java.nio.file.Paths;

import java.io.BufferedOutputStream;
import java.io.IOException;

public class ZipSample{
    public static void main(String[] args){
        //作成するZipファイルの名前
        var zipFile = Paths.get("sample.zip");
        
        try(var out = new BufferedOutputStream(Files.newOutputStream(zipFile));
            var zipout = new ZipOutputStream(out)){
            
            //Zipファイルに格納するファイル
            var toZipFile = Paths.get("ZipSample.java");
            var data = Files.readAllBytes(toZipFile);

            //Zipファイルの中にファイルを格納する
            zipout.putNextEntry(new ZipEntry("ZipSample.java"));
            zipout.write(data);
            zipout.closeEntry();
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

複数のファイルをZipに格納してみる

上記のソースコードでは1だけのファイルだったが今回はディレクトリを丸ごとZipファイルに格納サンプルを作ってみました。ディレクトリの中のファイルを列挙し1つ1つファイルを保存していく必要があり、その中にディレクトリがあればさらにその中のファイルを保存していきます。作成するZipファイルの名前と格納するディレクトリの名前は定数にしているので自分で編集して使ってみましょう。

import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;

import java.io.BufferedOutputStream;
import java.io.IOException;

public class ZipSample{
    //作成するZipファイルの名前
    private static final String ZIP_NAME = "sample.zip";
    //Zipに格納するディレクトリの名前
    private static final String DIRECTORY_NAME = "http";

    public static void main(String[] args){
        //作成するZipファイルの名前
        var zipFile = Paths.get(ZipSample.ZIP_NAME);
        
        try(var out = new BufferedOutputStream(Files.newOutputStream(zipFile));
            var zipout = new ZipOutputStream(out)){
            
            //Zipファイルに格納するファイル一覧を持つディレクトリ
            var directory = Paths.get(ZipSample.DIRECTORY_NAME);

            ZipSample.writeFile(zipout, directory);
        }catch(IOException e){
            e.printStackTrace();
        }
    }

    private static void writeFile(ZipOutputStream zipout, Path file){
        try(var files = Files.list(file)){
            files.forEach(path -> {
                try{
                    if(Files.isDirectory(path)){
                        //Pathがディレクトリの場合エントリだけ追加してディレクトリの内部もZipファイルへ
                        zipout.putNextEntry(new ZipEntry(path.toString()));
                        zipout.closeEntry();
                        ZipSample.writeFile(zipout, path);
                    }else{
                        var data = Files.readAllBytes(path);

                        //Zipファイルの中にファイルを格納する
                        zipout.putNextEntry(new ZipEntry(path.toString()));
                        zipout.write(data);
                        zipout.closeEntry();
                    }
                }catch(IOException e){
                    e.printStackTrace();
                }
            });
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}