アーカイブ

Java – zip圧縮する方法まとめ – ファイル指定/ディレクトリ指定

JavaでファイルやディレクトリをZIP圧縮するには、標準ライブラリのjava.util.zipパッケージを使用します。

ZipOutputStreamを用いて圧縮データを作成し、FileInputStreamでファイルを読み込むことで個別のファイルを圧縮できます。

ディレクトリを圧縮する場合は、再帰処理を用いてディレクトリ内の全ファイルを処理し、ZIPエントリを作成します。

ZIPエントリには相対パスを指定することでディレクトリ構造を保持できます。

圧縮後は必ずストリームをクローズしてください。

ファイルをZIP圧縮する方法

JavaでファイルをZIP圧縮するには、java.util.zipパッケージを使用します。

このパッケージには、ZIPファイルを作成するためのクラスが含まれています。

以下に、特定のファイルをZIP圧縮するサンプルコードを示します。

import java.io.FileInputStream; // ファイルを読み込むためのクラス
import java.io.FileOutputStream; // ファイルを書き込むためのクラス
import java.io.IOException; // 入出力例外を処理するためのクラス
import java.util.zip.ZipEntry; // ZIPエントリを表すクラス
import java.util.zip.ZipOutputStream; // ZIP出力ストリームを作成するクラス
public class App {
    public static void main(String[] args) {
        String sourceFile = "example.txt"; // 圧縮するファイル名
        String zipFile = "compressed.zip"; // 出力するZIPファイル名
        try {
            // ZIP出力ストリームを作成
            FileOutputStream fos = new FileOutputStream(zipFile);
            ZipOutputStream zos = new ZipOutputStream(fos);
            // ZIPエントリを作成
            ZipEntry zipEntry = new ZipEntry(sourceFile);
            zos.putNextEntry(zipEntry);
            // ファイルを読み込み、ZIPに書き込む
            FileInputStream fis = new FileInputStream(sourceFile);
            byte[] buffer = new byte[1024]; // バッファを作成
            int length;
            while ((length = fis.read(buffer)) >= 0) {
                zos.write(buffer, 0, length); // バッファの内容をZIPに書き込む
            }
            // ストリームを閉じる
            fis.close(); // 入力ストリームを閉じる
            zos.closeEntry(); // ZIPエントリを閉じる
            zos.close(); // ZIP出力ストリームを閉じる
            System.out.println("ファイルがZIP圧縮されました: " + zipFile); // 完了メッセージ
        } catch (IOException e) {
            e.printStackTrace(); // エラーを出力
        }
    }
}
ファイルがZIP圧縮されました: compressed.zip

このコードでは、example.txtというファイルをcompressed.zipというZIPファイルに圧縮しています。

ZipOutputStreamを使用してZIPファイルを作成し、ZipEntryを使って圧縮するファイルを指定します。

ファイルの内容はバッファを使って読み込み、ZIPファイルに書き込まれます。

ディレクトリをZIP圧縮する方法

JavaでディレクトリをZIP圧縮するには、指定したディレクトリ内のすべてのファイルとサブディレクトリを再帰的に処理する必要があります。

以下に、特定のディレクトリをZIP圧縮するサンプルコードを示します。

import java.io.File; // ファイルやディレクトリを扱うためのクラス
import java.io.FileInputStream; // ファイルを読み込むためのクラス
import java.io.FileOutputStream; // ファイルを書き込むためのクラス
import java.io.IOException; // 入出力例外を処理するためのクラス
import java.util.zip.ZipEntry; // ZIPエントリを表すクラス
import java.util.zip.ZipOutputStream; // ZIP出力ストリームを作成するクラス
public class App {
    public static void main(String[] args) {
        String sourceDir = "exampleDir"; // 圧縮するディレクトリ名
        String zipFile = "compressedDir.zip"; // 出力するZIPファイル名
        try {
            // ZIP出力ストリームを作成
            FileOutputStream fos = new FileOutputStream(zipFile);
            ZipOutputStream zos = new ZipOutputStream(fos);
            // ディレクトリをZIP圧縮するメソッドを呼び出す
            zipDirectory(sourceDir, zos, sourceDir.length() + 1);
            // ストリームを閉じる
            zos.close(); // ZIP出力ストリームを閉じる
            System.out.println("ディレクトリがZIP圧縮されました: " + zipFile); // 完了メッセージ
        } catch (IOException e) {
            e.printStackTrace(); // エラーを出力
        }
    }
    // ディレクトリをZIP圧縮するメソッド
    private static void zipDirectory(String dirPath, ZipOutputStream zos, int baseDirLength) throws IOException {
        File dir = new File(dirPath); // ディレクトリを表すFileオブジェクトを作成
        File[] files = dir.listFiles(); // ディレクトリ内のファイルとサブディレクトリを取得
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    // サブディレクトリの場合、再帰的に呼び出す
                    zipDirectory(file.getAbsolutePath(), zos, baseDirLength);
                } else {
                    // ファイルの場合、ZIPエントリを作成
                    FileInputStream fis = new FileInputStream(file);
                    String zipEntryName = file.getAbsolutePath().substring(baseDirLength); // ZIP内のパスを作成
                    ZipEntry zipEntry = new ZipEntry(zipEntryName);
                    zos.putNextEntry(zipEntry); // ZIPエントリを追加
                    // ファイルを読み込み、ZIPに書き込む
                    byte[] buffer = new byte[1024]; // バッファを作成
                    int length;
                    while ((length = fis.read(buffer)) >= 0) {
                        zos.write(buffer, 0, length); // バッファの内容をZIPに書き込む
                    }
                    // ストリームを閉じる
                    fis.close(); // 入力ストリームを閉じる
                    zos.closeEntry(); // ZIPエントリを閉じる
                }
            }
        }
    }
}
ディレクトリがZIP圧縮されました: compressedDir.zip

このコードでは、exampleDirというディレクトリをcompressedDir.zipというZIPファイルに圧縮しています。

zipDirectoryメソッドを使用して、ディレクトリ内のすべてのファイルとサブディレクトリを再帰的に処理し、各ファイルをZIPファイルに追加します。

ZIP内のパスは、元のディレクトリ構造を保持するように設定されています。

エラーハンドリングと注意点

JavaでファイルやディレクトリをZIP圧縮する際には、エラーハンドリングや注意点を考慮することが重要です。

以下に、エラーハンドリングの方法と注意すべきポイントをまとめます。

エラーハンドリング

  • IOExceptionの処理:
  • 入出力操作中に発生する可能性のあるIOExceptionを適切に処理することが重要です。

これにより、ファイルが存在しない場合やアクセス権がない場合などのエラーを捕捉できます。

  • 例外が発生した場合は、エラーメッセージを表示するか、ログに記録することで、問題の特定を容易にします。
try {
    // ZIP圧縮処理
} catch (IOException e) {
    System.err.println("エラーが発生しました: " + e.getMessage()); // エラーメッセージを表示
}
  • ファイルの存在確認:
  • 圧縮対象のファイルやディレクトリが存在するかを事前に確認することが推奨されます。

存在しない場合は、適切なメッセージを表示して処理を中止します。

File file = new File(sourceFile);
if (!file.exists()) {
    System.err.println("指定されたファイルが存在しません: " + sourceFile);
    return; // 処理を中止
}

注意点

  • ファイルサイズ:
  • 大きなファイルや多数のファイルを圧縮する場合、メモリやディスクの使用量に注意が必要です。

特に、ZIPファイルのサイズが大きくなると、処理に時間がかかることがあります。

  • ファイル名の重複:
  • 圧縮するディレクトリ内に同名のファイルが存在する場合、ZIPファイル内でのファイル名の重複に注意が必要です。

重複が発生すると、後から追加されたファイルが上書きされる可能性があります。

  • アクセス権:
  • 圧縮対象のファイルやディレクトリに対するアクセス権が不足している場合、IOExceptionが発生します。

特に、システムファイルや他のユーザーのファイルにアクセスする場合は注意が必要です。

  • サポートされていないファイル形式:
  • 一部のファイル形式や特殊なファイル(シンボリックリンクやデバイスファイルなど)は、ZIP圧縮に適していない場合があります。

これらのファイルを圧縮しようとすると、エラーが発生することがあります。

これらのエラーハンドリングと注意点を考慮することで、より堅牢で信頼性の高いZIP圧縮処理を実現できます。

応用例

JavaでのZIP圧縮の基本的な使い方を理解した後、さまざまな応用例を考えることができます。

以下に、いくつかの具体的な応用例を示します。

複数ファイルの一括圧縮

複数のファイルを一つのZIPファイルに圧縮することができます。

以下のサンプルコードでは、指定した複数のファイルをZIP圧縮します。

import java.io.FileInputStream; // ファイルを読み込むためのクラス
import java.io.FileOutputStream; // ファイルを書き込むためのクラス
import java.io.IOException; // 入出力例外を処理するためのクラス
import java.util.zip.ZipEntry; // ZIPエントリを表すクラス
import java.util.zip.ZipOutputStream; // ZIP出力ストリームを作成するクラス
public class App {
    public static void main(String[] args) {
        String[] sourceFiles = {"file1.txt", "file2.txt", "file3.txt"}; // 圧縮するファイル名
        String zipFile = "multipleFiles.zip"; // 出力するZIPファイル名
        try {
            FileOutputStream fos = new FileOutputStream(zipFile);
            ZipOutputStream zos = new ZipOutputStream(fos);
            for (String sourceFile : sourceFiles) {
                addToZipFile(sourceFile, zos); // 各ファイルをZIPに追加
            }
            zos.close(); // ZIP出力ストリームを閉じる
            System.out.println("複数のファイルがZIP圧縮されました: " + zipFile); // 完了メッセージ
        } catch (IOException e) {
            e.printStackTrace(); // エラーを出力
        }
    }
    private static void addToZipFile(String filePath, ZipOutputStream zos) throws IOException {
        FileInputStream fis = new FileInputStream(filePath);
        ZipEntry zipEntry = new ZipEntry(filePath);
        zos.putNextEntry(zipEntry);
        byte[] buffer = new byte[1024]; // バッファを作成
        int length;
        while ((length = fis.read(buffer)) >= 0) {
            zos.write(buffer, 0, length); // バッファの内容をZIPに書き込む
        }
        fis.close(); // 入力ストリームを閉じる
        zos.closeEntry(); // ZIPエントリを閉じる
    }
}
複数のファイルがZIP圧縮されました: multipleFiles.zip

特定の拡張子のファイルを圧縮

特定の拡張子を持つファイルのみをZIP圧縮することも可能です。

以下のサンプルコードでは、指定したディレクトリ内の.txtファイルのみを圧縮します。

import java.io.File; // ファイルやディレクトリを扱うためのクラス
import java.io.FileInputStream; // ファイルを読み込むためのクラス
import java.io.FileOutputStream; // ファイルを書き込むためのクラス
import java.io.IOException; // 入出力例外を処理するためのクラス
import java.util.zip.ZipEntry; // ZIPエントリを表すクラス
import java.util.zip.ZipOutputStream; // ZIP出力ストリームを作成するクラス
public class App {
    public static void main(String[] args) {
        String sourceDir = "exampleDir"; // 圧縮するディレクトリ名
        String zipFile = "textFiles.zip"; // 出力するZIPファイル名
        try {
            FileOutputStream fos = new FileOutputStream(zipFile);
            ZipOutputStream zos = new ZipOutputStream(fos);
            File dir = new File(sourceDir);
            File[] files = dir.listFiles((d, name) -> name.endsWith(".txt")); // .txtファイルのみを取得
            if (files != null) {
                for (File file : files) {
                    addToZipFile(file.getAbsolutePath(), zos); // 各.txtファイルをZIPに追加
                }
            }
            zos.close(); // ZIP出力ストリームを閉じる
            System.out.println("特定の拡張子のファイルがZIP圧縮されました: " + zipFile); // 完了メッセージ
        } catch (IOException e) {
            e.printStackTrace(); // エラーを出力
        }
    }
    private static void addToZipFile(String filePath, ZipOutputStream zos) throws IOException {
        FileInputStream fis = new FileInputStream(filePath);
        ZipEntry zipEntry = new ZipEntry(filePath);
        zos.putNextEntry(zipEntry);
        byte[] buffer = new byte[1024]; // バッファを作成
        int length;
        while ((length = fis.read(buffer)) >= 0) {
            zos.write(buffer, 0, length); // バッファの内容をZIPに書き込む
        }
        fis.close(); // 入力ストリームを閉じる
        zos.closeEntry(); // ZIPエントリを閉じる
    }
}
特定の拡張子のファイルがZIP圧縮されました: textFiles.zip

圧縮後のファイルの削除

圧縮が完了した後、元のファイルを削除することもできます。

以下のサンプルコードでは、圧縮後に元のファイルを削除します。

import java.io.File; // ファイルやディレクトリを扱うためのクラス
import java.io.FileInputStream; // ファイルを読み込むためのクラス
import java.io.FileOutputStream; // ファイルを書き込むためのクラス
import java.io.IOException; // 入出力例外を処理するためのクラス
import java.util.zip.ZipEntry; // ZIPエントリを表すクラス
import java.util.zip.ZipOutputStream; // ZIP出力ストリームを作成するクラス
public class App {
    public static void main(String[] args) {
        String sourceFile = "example.txt"; // 圧縮するファイル名
        String zipFile = "compressedWithDelete.zip"; // 出力するZIPファイル名
        try {
            FileOutputStream fos = new FileOutputStream(zipFile);
            ZipOutputStream zos = new ZipOutputStream(fos);
            addToZipFile(sourceFile, zos); // ファイルをZIPに追加
            zos.close(); // ZIP出力ストリームを閉じる
            System.out.println("ファイルがZIP圧縮されました: " + zipFile); // 完了メッセージ
            // 元のファイルを削除
            File file = new File(sourceFile);
            if (file.delete()) {
                System.out.println("元のファイルが削除されました: " + sourceFile); // 削除メッセージ
            } else {
                System.out.println("元のファイルの削除に失敗しました: " + sourceFile); // 削除失敗メッセージ
            }
        } catch (IOException e) {
            e.printStackTrace(); // エラーを出力
        }
    }
    private static void addToZipFile(String filePath, ZipOutputStream zos) throws IOException {
        FileInputStream fis = new FileInputStream(filePath);
        ZipEntry zipEntry = new ZipEntry(filePath);
        zos.putNextEntry(zipEntry);
        byte[] buffer = new byte[1024]; // バッファを作成
        int length;
        while ((length = fis.read(buffer)) >= 0) {
            zos.write(buffer, 0, length); // バッファの内容をZIPに書き込む
        }
        fis.close(); // 入力ストリームを閉じる
        zos.closeEntry(); // ZIPエントリを閉じる
    }
}
ファイルがZIP圧縮されました: compressedWithDelete.zip
元のファイルが削除されました: example.txt

これらの応用例を通じて、JavaでのZIP圧縮の可能性を広げることができます。

さまざまなシナリオに応じて、圧縮処理をカスタマイズすることが可能です。

まとめ

この記事では、Javaを使用してファイルやディレクトリをZIP圧縮する方法について詳しく解説しました。

具体的には、単一ファイルの圧縮から複数ファイルの一括圧縮、特定の拡張子を持つファイルの圧縮、圧縮後のファイル削除まで、さまざまな応用例を紹介しました。

これを機に、実際のプロジェクトや日常のタスクにZIP圧縮機能を取り入れて、効率的なファイル管理を実現してみてはいかがでしょうか。

関連記事

Back to top button