【C#】Zipアーカイブから特定のファイルだけを解凍・抽出する (ExtractToFile)

Zipファイルをすべて解凍するのではなく、中身を検索して「特定のファイル1つだけ」を取り出したい場合があります。

ZipArchiveEntry クラスの ExtractToFile メソッドを使用すると、取得したエントリ(ファイル情報)を直接指定したパスにファイルとして書き出すことができます。

目次

実装サンプル:ログアーカイブからの特定ログ抽出

以下のコードでは、Zipファイル(Logs.zip)の中から、特定のエラーログファイル(Error_2025.txt)を探し出し、それだけを解凍して取り出す処理を実装しています。

サンプルコード

using System;
using System.IO;
using System.IO.Compression; // 参照設定が必要な場合があります

public class Program
{
    public static void Main()
    {
        string zipPath = "Logs.zip";
        
        // Zip内のファイルパス(フォルダ階層がある場合は "logs/error.txt" のように指定)
        string targetEntryName = "Error_2025.txt";
        
        // 解凍後のファイル名
        string outputPath = "Extracted_ErrorLog.txt";

        // 1. テスト環境の準備 (Zipファイルの作成)
        if (File.Exists(zipPath)) File.Delete(zipPath);
        using (var archive = ZipFile.Open(zipPath, ZipArchiveMode.Create))
        {
            archive.CreateEntryFromFile(CreateDummyFile("System.log"), "System.log");
            archive.CreateEntryFromFile(CreateDummyFile("Error_2025.txt"), targetEntryName);
        }

        try
        {
            // 2. Zipファイルを読み取りモードで開く
            using (ZipArchive archive = ZipFile.OpenRead(zipPath))
            {
                // 3. 指定した名前のエントリを取得する
                ZipArchiveEntry entry = archive.GetEntry(targetEntryName);

                if (entry != null)
                {
                    Console.WriteLine($"ファイルが見つかりました。サイズ: {entry.Length} bytes");

                    // 4. ファイルとして抽出(保存)する
                    // 第2引数 overwrite: true で上書きを許可
                    entry.ExtractToFile(outputPath, overwrite: true);

                    Console.WriteLine($"抽出完了: {Path.GetFullPath(outputPath)}");
                }
                else
                {
                    Console.WriteLine($"エラー: {targetEntryName} はアーカイブ内に存在しません。");
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("エラーが発生しました: " + ex.Message);
        }
    }

    // ダミーファイル作成用ヘルパー
    static string CreateDummyFile(string name)
    {
        File.WriteAllText(name, "Log content...");
        return name;
    }
}

実行結果

ファイルが見つかりました。サイズ: 14 bytes
抽出完了: C:\Work\Extracted_ErrorLog.txt

解説と技術的なポイント

1. ZipArchiveEntry.ExtractToFile

このメソッドは、エントリの内容を指定したパスにファイルとして書き出します。 ストリームを開いて CopyTo などでデータを移し替える処理を自前で書く必要がなく、非常に簡潔に実装できます。

// (従来の手法) ストリームを使う場合
// using (var reader = entry.Open())
// using (var writer = File.OpenWrite(outputPath))
// {
//     reader.CopyTo(writer);
// }

// (推奨) ExtractToFileを使う場合
entry.ExtractToFile(outputPath, overwrite: true);

2. エントリの検索 (GetEntry)

archive.GetEntry("パス") は、大文字小文字を区別して完全一致するエントリを探します。 もし、大文字小文字を無視して探したい場合(例: readme.txt でも README.TXT でもヒットさせたい場合)は、archive.Entries に対して LINQ を使って検索する必要があります。

// 大文字小文字を無視して検索する例
var entry = archive.Entries.FirstOrDefault(e => 
    e.FullName.Equals(targetEntryName, StringComparison.OrdinalIgnoreCase));
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

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

目次