0.前置き

Webアプリを作るときにサーバーサイドで複数のファイルをZip化させるにはどんな手段があるのかなってことを調べてました。
.NET標準のクラスでZip化するもの(System.IO.Compression.GZipStream, System.IO.Packaging.ZipPackage)
もあるのですが、複数ファイルをまとめる(アーカイブする)機能を実現するのはちょっとめんどくさそうです。
そこで今回はDotNetZipというライブラリーを使ってみることにしました。
サンプルはASP.NET MVCでWebアプリケーンションにしました。

1.DotNetZipの紹介

DotNetZipは、Ms-PLで公開されているZipを扱うライブラリーです。
とにかくなんでもできるとCodePlexでは言っておられます。
CodePlexのサイトはこちら

2.インストール

Nugetでインストールできます。
CodePlexからはサンプルアプリケーションが一緒に入っているソースコードをダウンロードすることができます。
サンプルがたくさん入っていますし、ドキュメントも大量にあるので使うことに不自由しません。

3.実際に使ってみる

ASP.NET MVCでサンプルを作ってみました。主要な部分のみ抜き出し記載します。
(今回はASP.NET MVC4とVisualStudio2011を使っています。)

HomeController#Downloadの実装部分
Home/IndexのビューにDownloadアクションを呼び出すアクションリンクを配置してあります。
呼び出させれるDownloadアクションは以下の通りです。

[sourcecode language=”csharp”]
public class HomeController : Controller
{
public ZipFileResult Download()
{
var filePathList = new List<string>{
Server.MapPath(@"~/Content\files\ファイル1.txt"),
Server.MapPath(@"~/Content\files\ファイル2.txt"),
Server.MapPath(@"~/Content\files\ファイル3.txt"),
Server.MapPath(@"~/Content\files\ファイル4.txt"),
Server.MapPath(@"~/Content\files\ファイル5.txt"),
Server.MapPath(@"~/Content\files\file6.txt")
};

var zipFileName = "ZippedFile.zip";

using (var zipFile = new ZipFile(Encoding.GetEncoding("shift_jis")))
{
zipFile.AddFiles(filePathList, "");
return new ZipFileResult(zipFile, zipFileName);
}
}
}
[/sourcecode]

複数ファイルも、zipFile.AddFiles(filePathList, “”) としてあげればいっきにアーカイブ化できます。
1つ目の引数がZip化するファイルのパス、2つめの引数でZip化後のフォルダー内でのファイルの場所を指定します。
詰め込んだZipFileのオブジェクトをZipFileResultというカスタムActionResultに渡します。

ZipFileResultの実装部分
ExecuteResultでHttpContext.ResponseにZipFileオブジェクトを書きだしてあげます。
こちらを参考にしました。)
[sourcecode language=”csharp”]
public class ZipFileResult : ActionResult
{
public ZipFile zip { get; set; }
public string fileName { get; set; }

public ZipFileResult(ZipFile zip, string fileName)
{
this.zip = zip;
this.fileName = fileName;
}

public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.ContentType = "application/zip";
response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
zip.Save(response.OutputStream);
response.End();
}
}
[/sourcecode]

4.サンプルを書いてみての補足

このライブラリーも便利ですね。
ファイルの追加とか圧縮とか、属性をもろもろつけるとか簡単にできるそうです。
唯一の注意点は日本語のファイル名のファイルをアーカイブ対象にする場合には、
ZipFileのコンストラクタでエンコーディング方式を指定する必要があるということです。

5.サンプルコード

サンプルコードはgithubにホスティングしてあります。
DotNetZipのサンプルWebアプリケーション

6.最後に

最近、だんだん手をつける範囲が広くなってきた気がします。
深堀はできないけど、薄く広く学んだことを書き留めていこうと思います。
参考にしたサイト
astel-labs.net : C#でZip圧縮形式ファイルの操作