日曜プログラマの備忘録

『日曜プログラマ.com』公式ブログ

単一ディレクトリをZIP形式で圧縮

2025-12-28 22:25:31
2026-01-12 18:38:02
目次
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

デスクトップ上の単一ディレクトリを圧縮(ZIP形式)し、デスクトップ上にZIPファイルを作成する。

/* デスクトップパスの取得 */

Path desktopPath = null;
Path userHomePath = Paths.get(System.getProperty("user.home"));
String desktopPathString;

for (String name : new String[] {"Desktop", "デスクトップ"}) {
    desktopPath = userHomePath.resolve(name);

    if (Files.isDirectory(desktopPath)) {
        desktopPathString = desktopPath.toString();
        break;
    } else {
        desktopPath = null;
    }
}

if (desktopPath == null) {
    desktopPathString = userHomePath.toString();
}


/* 単一ディレクトリの圧縮(ZIP形式) */

String zipPathString = desktopPathString + File.separator + "sample.zip";

try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipPathString))) {
    Path targetPath = Paths.get(desktopPathString, "sample");
    compressDirectory(targetPath, targetPath.getFileName().toString(), zipOutputStream);  // 「ディレクトリの圧縮(ZIP形式)」メソッドの呼び出し
} catch (FileNotFoundException e) {
    System.out.println("ディレクトリの圧縮中にエラーが発生しました! (" + e.getMessage() + ")");
} catch (IOException e) {
    System.out.println("ディレクトリの圧縮中にエラーが発生しました! (" + e.getMessage() + ")");
}

上記コードから呼び出される「ディレクトリの圧縮(ZIP形式)」メソッド。

private void compressDirectory(Path targetPath, String parentDirectoryName, ZipOutputStream zipOutputStream) {
    try (DirectoryStream<Path> directoryStreamPath = Files.newDirectoryStream(targetPath)) {
        String entryName;
        int bytes;
        byte[] dataBuffer = new byte[16384];

        for (Path path : directoryStreamPath) {
            entryName = parentDirectoryName + "/" + path.getFileName().toString();  // ZIPエントリ名の区切り文字には「/」を使用すること

            if (Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
                zipOutputStream.putNextEntry(new ZipEntry(entryName + "/"));
                zipOutputStream.closeEntry();
                compressDirectory(path, entryName, zipOutputStream);
            } else {
                zipOutputStream.putNextEntry(new ZipEntry(entryName));

                try (InputStream inputStream = Files.newInputStream(path)) {
                    while ((bytes = inputStream.read(dataBuffer)) != -1) {
                        zipOutputStream.write(dataBuffer, 0, bytes);
                    }
                }

                zipOutputStream.closeEntry();
            }
        }
    } catch (IOException e) {
        System.out.println("ディレクトリの圧縮中にエラーが発生しました! (" + e.getMessage() + ")");
    }
}

この記事を書いた人

ASAWA Kōichi

『日曜プログラマ.com』作者兼管理人