【C#】Zipファイル内の特定のファイルを削除する (ZipArchiveEntry.Delete)

Zipアーカイブ(圧縮ファイル)を作成した後、特定のファイルだけを取り除きたい場合があります。 例えば、ログファイルを含めて圧縮してしまったが後から削除したい場合や、古い設定ファイルをアーカイブから除外したい場合などです。

この操作を行うには、ZipFile.OpenZipArchiveMode.Update モードを指定し、対象のエントリを取得して Delete() メソッドを呼び出します。

目次

実装サンプル:不要な一時ファイルの削除

以下のコードでは、Zipファイル内にある「temp.dat」という不要なファイルを検索し、存在する場合にのみ削除する処理を行っています。

サンプルコード

using System;
using System.IO;
using System.IO.Compression;

public class Program
{
    public static void Main()
    {
        string zipPath = "ProjectArchive.zip";
        string targetFileName = "temp.dat";

        // 1. テスト環境の準備
        // Zipファイルを作成し、削除対象のファイルを含めておきます
        if (File.Exists(zipPath)) File.Delete(zipPath);
        
        using (ZipArchive archive = ZipFile.Open(zipPath, ZipArchiveMode.Create))
        {
            archive.CreateEntryFromFile("main.exe", "main.exe"); // ダミー
            // これが削除対象
            ZipArchiveEntry entry = archive.CreateEntry(targetFileName); 
        }

        Console.WriteLine("--- 処理前のZip内 ---");
        ShowZipContents(zipPath);


        // 2. Zipファイルからファイルを削除する処理
        try
        {
            // ZipArchiveMode.Update で開くことが必須です
            using (ZipArchive archive = ZipFile.Open(zipPath, ZipArchiveMode.Update))
            {
                // 削除したいファイルをパス(名前)で指定して取得
                // ※Zip内のパスは基本的に大文字小文字を区別します
                ZipArchiveEntry entry = archive.GetEntry(targetFileName);

                if (entry != null)
                {
                    // エントリ(ファイル)を削除
                    entry.Delete();
                    Console.WriteLine($"\n削除しました: {targetFileName}");
                }
                else
                {
                    Console.WriteLine($"\nファイルが見つかりませんでした: {targetFileName}");
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("エラー: " + ex.Message);
        }

        Console.WriteLine("\n--- 処理後のZip内 ---");
        ShowZipContents(zipPath);
    }

    // Zipの中身を表示するヘルパーメソッド
    static void ShowZipContents(string path)
    {
        using (ZipArchive archive = ZipFile.OpenRead(path))
        {
            foreach (var e in archive.Entries)
            {
                Console.WriteLine($" - {e.FullName}");
            }
        }
    }
}

実行結果

--- 処理前のZip内 ---
 - main.exe
 - temp.dat

削除しました: temp.dat

--- 処理後のZip内 ---
 - main.exe

解説と技術的なポイント

1. ZipArchiveMode.Update

ファイルを削除するには、アーカイブそのものを書き換える必要があるため、必ず Update モードで開きます。Read モードでは削除できません。

2. GetEntry の挙動

archive.GetEntry("パス") は、指定したファイルがZip内に存在すれば ZipArchiveEntry オブジェクトを返し、存在しなければ null を返します。 いきなり .Delete() を呼ぶと NullReferenceException になる可能性があるため、サンプルコードのように必ず null チェックを行うのが安全です。

3. ディレクトリ階層の指定

Zip内のサブフォルダにあるファイルを消したい場合は、パスを含めて指定します。 例:archive.GetEntry("logs/error.log") ※Windows環境で作られたZipの場合、区切り文字が \ になっているケースもあるため、パスの指定には注意が必要です(基本は / 推奨)。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次