中堅プログラマーの備忘録

忘れっぽくなってきたので備忘録として・・・

【C#.net】ZipArchiveクラスを使ってzipファイルの解凍処理を行う

1.概要

アプリケーションでZipファイルの解凍処理を行う場合
サードパーティ製のものを使うという選択肢が一般的だったかと思います。
フリーのライブラリである【SharpZipLib】を使ったこともありますが
これはGPLライセンスであるため、ちょっと使い勝手が悪いです。
(※解釈も人によって異なるので正直面倒くさい・・・)


今回は.Net 4.5からZipArchiveクラスというのが追加になったので
これを使ってみたいと思います。

2.準備をする

ZipArchiveクラスを使用するため【System.IO.Compression.FileSystem.dll】を追加します。
また、ZipFileクラスもつかうので【System.IO.Compression.dll】も追加します。


参照の追加から
下図のとおり追加します。

f:id:tsu--kun:20191203160337p:plain

これでとりあえず準備は完了です。

3.スクリプト

using System;
using System.Windows.Forms;
using System.IO.Compression;
using System.IO;

namespace UnzipTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // ZIPファイルのパス
            string ZipPath = @"C:\test.zip";
           
            // 解凍先ディレクトリの確認(存在しない場合は作成する)
            string ExtractPath = @"C:\unziptest";
            if (Directory.Exists(ExtractPath) == false)
            {
                Directory.CreateDirectory(ExtractPath);
            }

            // ZIPファイルを開いてZipArchiveオブジェクトを作成
            using (ZipArchive archive = ZipFile.OpenRead(ZipPath))
            {
                Console.WriteLine("解凍処理数は{0}です。", archive.Entries.Count);

                // 以下解凍処理
                foreach (ZipArchiveEntry entry in archive.Entries)
                {

                    string fullpath = Path.Combine(ExtractPath, entry.FullName);

                    if (entry.Name == "")
                    {
                        Console.WriteLine("ディレクトリ:{0}の処理を開始", fullpath);
                        // ディレクトリの場合
                        if (Directory.Exists(fullpath) == true)
                        {
                            // 存在するので何もしない
                            Console.WriteLine("ディレクトリ:{0}は存在するため処理を中止しました。", fullpath);
                        }
                        else
                        {
                            // 存在しないので作成
                            Directory.CreateDirectory(fullpath);
                            Console.WriteLine("ディレクトリ:{0}を解凍しました。", fullpath);
                        }
                    }
                    else
                    {
                        Console.WriteLine("ファイル{0}の処理を開始", fullpath);
                        if (Directory.Exists(Path.GetDirectoryName(fullpath)) == false)
                        {
                            Directory.CreateDirectory(Path.GetDirectoryName(fullpath));
                        }
                        // ファイルの場合
                        if (File.Exists(fullpath) == true)
                        {
                            // ファイルの場合の場合
                            entry.ExtractToFile(fullpath, true);
                            Console.WriteLine("ファイル:{0}を上書きしました。", fullpath);
                        }else
                        {
                            entry.ExtractToFile(fullpath, true);
                            Console.WriteLine("ファイル:{0}を解凍しました。", fullpath);
                        }
                    }
                }
            }
        }
    }
}

4.解凍処理の流れ

まずは指定パスにあるzipのアーカイブを開き【ZipArchive】に格納します。

using (ZipArchive archive = ZipFile.OpenRead(ZipPath))


アーカイブ内のエントリのコレクションをひとつづつ処理していきます。

foreach (ZipArchiveEntry entry in archive.Entries)
if (entry.Name == "")

を確認することで、ファイルかディレクトリかを判断します。
【true】の場合はディレクトリ
【false】の場合はファイルと判断します。

entry.ExtractToFile(fullpath, true);

第二引数に【true】を設定することで同じファイル名が存在するときは
上書き処理を行います。

5.実行結果

下記のファイル構成に

C:\unziptest
  |--test1
  |    `--test.png
  |--test.png
  `--test.txt

下記の構成のzipファイルを解凍します。

test.zip
  |--test1
  |    `--test_test1.png
  |--test1
  |    |--test_test2.png
  |    `--test_test2.txt
  |--test.png
  `--test.txt


結果のログは下記のとおりとなりました。

解凍処理数は5です。
ファイルC:\unziptest\test.pngの処理を開始
ファイル:C:\unziptest\test.pngを上書きしました。
ファイルC:\unziptest\test.txtの処理を開始
ファイル:C:\unziptest\test.txtを上書きしました。
ファイルC:\unziptest\test1/test_test1.pngの処理を開始
ファイル:C:\unziptest\test1/test_test1.pngを解凍しました。
ファイルC:\unziptest\test2/test_test2.pngの処理を開始
ファイル:C:\unziptest\test2/test_test2.pngを解凍しました。
ファイルC:\unziptest\test2/test_test2.txtの処理を開始
ファイル:C:\unziptest\test2/test_test2.txtを解凍しました。