Zipファイルに圧縮する (.NET Framework 4.5 以降) - C#

C#で .NET Framework 4.5 以降でZipファイルに圧縮するコードを紹介します。

概要

.NET Framework 4.5 以降ではZipArchive クラスを利用することで、外部のライブラリを利用せずに、Zipファイルの圧縮処理が利用できます。
また、ディレクトリ内のファイルをまとめて圧縮する場合は、ZipFile クラスを利用できます。
この記事では、Zipファイルを作成し、ファイルやデータを圧縮するコードを紹介します。
補足
.NET Framework 4.5 以前では DotNetZip ライブラリを利用して圧縮処理を実装できます。詳細はこちらの記事を参照してください。

プログラム例1 : ストリームで書き込む内容をZipファイルに圧縮する

Windows Form アプリケーションを作成します。

UI

下図のウィンドウを作成します。ウィンドウにボタンを1つ配置します。

コード

下記のコードを記述します。ボタンのクリックイベントを実装します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.IO.Compression;

namespace DotNetZipArchive
{
  public partial class FormStreamZipArchive : Form
  {
    public FormStreamZipArchive()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      FileStream fs = new FileStream("test.zip", FileMode.CreateNew);
      ZipArchive za = new ZipArchive(fs, ZipArchiveMode.Create);
      ZipArchiveEntry zae = za.CreateEntry("file1.txt");
      StreamWriter sw = new StreamWriter(zae.Open());
      sw.WriteLine("ぺんぎんクッキー");
      sw.WriteLine("らくだキャラメル");
      sw.WriteLine("しろくまアイス");
      sw.WriteLine("あひるサブレ");
      sw.WriteLine("ぺりかんマカロン");

      sw.Close();
      za.Dispose();
      fs.Close();
    }
  }
}

解説

FileStreamを作成し、Zipファイルを作成します。
  FileStream fs = new FileStream("test.zip", FileMode.CreateNew);

ZipArchive オブジェクトを作成します。第一引数にはZipファイルのファイルストリームを与えます。ZipArchiveも新規作成のため、第二引数にはZipArchiveMode.Createを与えます。
  ZipArchive za = new ZipArchive(fs, ZipArchiveMode.Create);

ZipArchive オブジェクトの CreateEntry メソッドを呼び出し、Zipファイル内に配置するファイルを作成します。CreateEntry メソッドの第一引数に作成するファイル名を与えます。
  ZipArchiveEntry zae = za.CreateEntry("file1.txt");
CreateEntry メソッドで作成された ZipArchiveEntry オブジェクトのOpen メソッドを呼び出します。Zipアーカイブ内の圧縮ファイルのストリームオブジェクトが返されますので、 ストリームオブジェクトの WriteLine メソッドを呼び出してZipアーカイブ内のファイルに情報を書き込みます。
      StreamWriter sw = new StreamWriter(zae.Open());
      sw.WriteLine("ぺんぎんクッキー");
      sw.WriteLine("らくだキャラメル");
      sw.WriteLine("しろくまアイス");
      sw.WriteLine("あひるサブレ");
      sw.WriteLine("ぺりかんマカロン");

情報の書き込みができたら、ストリームやZipArchive オブジェクトを開放します。
  sw.Close();
  za.Dispose();
  fs.Close();

参考

上記のコードは例外処理などが入っていないシンプルなコードですが、例外処理やusingを利用したコードが以下になります。
using を利用したコード
private void button2_Click(object sender, EventArgs e)
{
  using (FileStream fs = new FileStream("test.zip", FileMode.CreateNew)) {
    using (ZipArchive za = new ZipArchive(fs, ZipArchiveMode.Create)) {
      ZipArchiveEntry zae = za.CreateEntry("file1.txt");
      using (StreamWriter sw = new StreamWriter(zae.Open())) {
        sw.WriteLine("ぺんぎんクッキー");
        sw.WriteLine("らくだキャラメル");
        sw.WriteLine("しろくまアイス");
        sw.WriteLine("あひるサブレ");
      }
    }
  }
}
例外処理を利用したコード
private void button2_Click(object sender, EventArgs e)
{
  FileStream fs = new FileStream("test.zip", FileMode.CreateNew);
  try {
    ZipArchive za = new ZipArchive(fs, ZipArchiveMode.Create);
    try {
      ZipArchiveEntry zae = za.CreateEntry("file1.txt");
      StreamWriter sw = null;
      try {
        sw = new StreamWriter(zae.Open());
        sw.WriteLine("ぺんぎんクッキー");
        sw.WriteLine("らくだキャラメル");
        sw.WriteLine("しろくまアイス");
        sw.WriteLine("あひるサブレ");
        sw.WriteLine("ぺりかんマカロン");
      }
      finally {
        sw.Close();
      }
    }
    finally {
      za.Dispose();
    }
  }
  finally {
    fs.Close();
  }
}

実行結果

上記のプロジェクトファイルを実行します。下図のウィンドウが表示されます。[button1]をクリックします。 ボタンをクリックしても画面上の変化はありません。


実行ファイルが配置されているフォルダを開きます。"test.zip" ファイルが作成されていることが確認できます。


test.zip ファイルを展開します。


展開されたtest.zipファイル内に、file1.txt ファイルがあることが確認できます。


file1.txt を開きます。ファイルの内容は下図の通りです。コードで記述した "ぺんぎんクッキー" などの文字列がファイル内に書き込みされていることが確認できます。

プログラム例2 : ファイルをZipファイルに圧縮する

UI

下図のウィンドウを作成します。ウィンドウにボタンを1つ、複数行テキストボックス、OpenFileDialog を配置します。


OpenFileDialogのMultiselectプロパティを Trueに変更します。

コード

下記のコードを記述します。button1のクリックイベントの実装コードを記述しています。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.IO.Compression;

namespace DotNetZipArchive
{
  public partial class FormFileZipArchive : Form
  {
    public FormFileZipArchive()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      if (openFileDialog1.ShowDialog() == DialogResult.OK) {
        if (File.Exists("test.zip") == true) File.Delete("test.zip");

        FileStream fs = new FileStream("test.zip", FileMode.CreateNew);
        ZipArchive za = new ZipArchive(fs, ZipArchiveMode.Create);
        foreach (string filename in openFileDialog1.FileNames) {
          za.CreateEntryFromFile(filename, Path.GetFileName(filename));
          textBox1.Text += filename+"を圧縮しました\r\n";
        }
        za.Dispose();
        fs.Close();

        textBox1.Text += "圧縮処理が終了しました\r\n";
      }
    }
  }
}

解説

OpenFileDialogを開き、ファイルを選択します。
  if (openFileDialog1.ShowDialog() == DialogResult.OK) {
    //中略
  }
既にtest.zipファイルが存在している場合、ストリームを開いた際にIOException例外が発生するため、test.zipファイルが存在する場合はファイルを削除します。
    if (File.Exists("test.zip") == true) File.Delete("test.zip");

test.zip ファイルのFileStreamを作成します。ZipArchiveオブジェクトも作成します。
    FileStream fs = new FileStream("test.zip", FileMode.CreateNew);
    ZipArchive za = new ZipArchive(fs, ZipArchiveMode.Create);

ZipArchiveオブジェクトの CreateEntryFromFile メソッドを呼び出します。第一引数に圧縮するファイルのパスを与えます。 第二引数にZipファイル内でのエントリー名を与えます。
この処理をOpenFileDialogで選択した各ファイルに対して実行します。
    foreach (string filename in openFileDialog1.FileNames) {
      za.CreateEntryFromFile(filename, Path.GetFileName(filename));
      textBox1.Text += filename+"を圧縮しました\r\n";
    }

ファイルの圧縮が終わったら、ZipArchiveオブジェクトとファイルストリームを閉じます。
  za.Dispose();
  fs.Close();
  textBox1.Text += "圧縮処理が終了しました\r\n";

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。[button1]をクリックします。


ファイルを開くダイアログが表示されます。圧縮するファイルを選択します。


圧縮処理が実行されます。下図のメッセージが表示されます。


プログラムの実行フォルダを開きます。実行ファイルと同じ位置に "test.zip"ファイルが作成されていることが確認できます。


"test.zip"ファイルを開きます。選択したファイルが圧縮されて格納されていることが確認できます。


圧縮されているファイルを展開してファイル内を確認します。元のファイルと内容やサイズが一致していることを確認します。


ファイルをZipファイルに圧縮できました。

プログラム例3 : 指定したディレクトリのファイルをZipファイルに圧縮する

指定したディレクトリのファイルをすべてZIPファイルに圧縮する場合は、ZipFile.CreateFromDirectory() メソッドを利用します。

UI

下図のフォームを作成します。ボタンと複数行のテキストボックス、FolderBrowserDialog を配置します。

コード

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.IO.Compression;

namespace DotNetZipArchive
{
  public partial class FormDirectoryZipArchive : Form
  {
    public FormDirectoryZipArchive()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) {
        if (File.Exists("test.zip") == true) File.Delete("test.zip");
        ZipFile.CreateFromDirectory(folderBrowserDialog1.SelectedPath, "test.zip");
        textBox1.Text = folderBrowserDialog1.SelectedPath + "ディレクトリのファイル圧縮しました";
      }
    }
  }
}

解説

FolderBrowserダイアログを表示してZIPファイルで圧縮するディレクトリを選択します。
  if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) {
    /* 中略 */
  }

ディレクトリが選択されたら、実行ファイルが配置されているパスに "test.zip" ファイルが存在するか確認します。 ファイルが存在する場合は、"test.zip" ファイルを削除します。
    if (File.Exists("test.zip") == true) File.Delete("test.zip");

ZipFile.CreateFromDirectory() メソッドを呼び出します。第一引数に圧縮するディレクトリのパスを与えます。 第二引数に出力先のZIPファイル名を与えます。今回は FolderBrowserダイアログで指定したディレクトリをCreateFromDirectory メソッドの 第一引数に与え、第二引数には "test.zip" を与えて実行ファイルを配置しているパスの位置に test.zip ファイルを作成します。
処理後にテキストボックスにメッセージを表示します。
    ZipFile.CreateFromDirectory(folderBrowserDialog1.SelectedPath, "test.zip");
    textBox1.Text = folderBrowserDialog1.SelectedPath + "ディレクトリのファイル圧縮しました";

実行結果

ファイルを圧縮するディレクトリを準備します。圧縮するファイル一式を c:\data\comp フォルダに配置します。


上記のプロジェクトを実行します。下図のウィンドウが表示されます。


[button1]をクリックします。[フォルダーの選択]ダイアログが表示されます。


先ほど準備した c:\data\comp フォルダを選択します。


フォルダを選択すると圧縮処理が実行されます。処理が完了するとテキストボックスに「c:\data\compディレクトリのファイルを圧縮しました」の メッセージが表示されます。


実行プログラムが配置されているディレクトリをエクスプローラーで表示します。"test.zip" ファイルが作成されていることが確認できます。


test.zip ファイル内のファイルを確認します。


圧縮されたファイルを展開して表示してみます。元のファイルと同じ内容が表示できていることが確認できますい。


指定したフォルダ内のファイルをZIPファイルに圧縮できました。

著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2023-02-26
作成日: 2021-02-26
iPentec all rights reserverd.