DOBON.NET

#ziplib(SharpZipLib)を使ってZIP圧縮、展開(解凍)、リスト表示などを行う

ここでは、ZIP書庫を扱うことができるフリーのライブラリである#ziplib(SharpZipLib)を使う方法を紹介します。この記事を書いている時点での最新版のバージョンは0.85.5です。

なお、.NET FrameworkでZIP書庫を扱う方法は、これ以外にも、以下の記事で説明しているような方法もあります。

補足:#ziplibのライセンスは、基本的にはGNU General Public License(GPL)です。GPLのライブラリにリンクするプログラムは、静的なリンクはもちろん、動的にリンクする場合でさえGPLとしなければいけないとする意見があります。しかし#ziplibは、独立したモジュールとしてリンクして使用する場合は例外として、商用のクローズドソースアプリケーションでも使用できるようです。ただし、この説明が正しいという保証はできませんので、#ziplibのライセンスは必ずご自分でご確認ください。

#ziplibは「.NET Zip Library #ziplib (SharpZipLib)」からダウンロードできます。ここで紹介するサンプルでは、ダウンロードしたDLL(ICSharpCode.SharpZipLib.dll)がプロジェクトの参照設定に追加されているものとします。

FastZipクラスで圧縮(書庫を作成)する

FastZipクラスを使用すると、驚くほど簡単にZIP書庫の作成や展開を行うことができます。ZIP書庫を作成するにはCreateZipメソッドを、展開するにはExtractZipメソッドを使用します。

以下の例では、"C:\doc"フォルダ以下のすべてのファイルとフォルダを圧縮し、"C:\test.zip"というZIP書庫を作っています。

VB.NET
コードを隠すコードを選択
'作成するZIP書庫のパス 
'ファイルが既に存在している場合は、上書きされる 
Dim zipFileName As String = "C:\test.zip"
'圧縮するフォルダのパス 
Dim sourceDirectory As String = "C:\doc"
'サブディレクトリも圧縮するかどうか 
Dim recurse As Boolean = True

'FastZipオブジェクトの作成 
Dim fastZip As New ICSharpCode.SharpZipLib.Zip.FastZip()
'空のフォルダも書庫に入れるか。デフォルトはfalse 
fastZip.CreateEmptyDirectories = True
'ZIP64を使うか。デフォルトはDynamicで、状況に応じてZIP64を使う 
'(大きなファイルはZIP64でしか圧縮できないが、対応していないアーカイバもある) 
fastZip.UseZip64 = ICSharpCode.SharpZipLib.Zip.UseZip64.Dynamic
'パスワードを設定するには次のようにする 
'fastZip.Password = "password"

'圧縮してZIP書庫を作成 
fastZip.CreateZip(zipFileName, sourceDirectory, recurse, Nothing, Nothing)
C#
コードを隠すコードを選択
//作成するZIP書庫のパス
//ファイルが既に存在している場合は、上書きされる
string zipFileName = @"C:\test.zip";
//圧縮するフォルダのパス
string sourceDirectory = @"C:\doc";
//サブディレクトリも圧縮するかどうか
bool recurse = true;

//FastZipオブジェクトの作成
ICSharpCode.SharpZipLib.Zip.FastZip fastZip =
    new ICSharpCode.SharpZipLib.Zip.FastZip();
//空のフォルダも書庫に入れるか。デフォルトはfalse
fastZip.CreateEmptyDirectories = true;
//ZIP64を使うか。デフォルトはDynamicで、状況に応じてZIP64を使う
//(大きなファイルはZIP64でしか圧縮できないが、対応していないアーカイバもある)
fastZip.UseZip64 = ICSharpCode.SharpZipLib.Zip.UseZip64.Dynamic;
//パスワードを設定するには次のようにする
//fastZip.Password = "password";

//圧縮してZIP書庫を作成
fastZip.CreateZip(zipFileName, sourceDirectory, recurse, null, null);

ファイルとフォルダのフィルタ

CreateZipメソッドの4番目のパラメータにファイルのフィルタを指定することができます。これによって、例えば拡張子が".txt"のファイルだけを書庫に入れるといったように、書庫に入れるファイルを指定することができます。

フィルタの書式は、* や ? などのワイルドカードを使ったものではなく、正規表現を使ったものになります。例えば、拡張子が".txt"のファイルのみを対象とするならば、フィルタに"\.txt$"を指定します。なお、正規表現について詳しくは、「正規表現の基本」をご覧ください。

このフィルタと比較されるファイルのパスは、フルパスです。よって、例えば"readme.txt"という名前のファイルだけを対象としたいときに、フィルタを"^readme\.txt$"としてもうまくいきません。

補足:それでは"readme.txt"という名前のファイルだけを対象としたいときはフィルタにどのような記述をすればよいのかですが、これが意外と難しいです。普通に考えると"\\readme.txt$"(C#では、@"\\readme.txt$")で良さそうですが、これだとうまくいきません。"\\\\readme.txt$"(C#では、@"\\\\readme.txt$")とするとうまくいきます。なぜこのようにしないといけないのかは分かりません。(この問題は、v0.86.0.518で修正されました。v0.86.0.518からは逆に"\\\\readme.txt$"はダメで、"\\readme.txt$"としなければなりません。この修正について詳しくはこちら。)

このフィルタには、複数の正規表現パターンを指定することもできます。この場合、各パターンを";"で区切ります。さらに、除外するファイルを指定することもでき、このときは、正規表現パターンの先頭に"-"を付けます。同様に、追加するファイルを指定するときは、パターンの先頭に"+"を付けますが、何もつけなくても同じになります。

例えば、拡張子が".txt"か".rtf"のファイルを対象とし、"コピー"という文字が入っているファイルを対象から外すのであれば、フィルタを"\.txt$;\.rtf$;-コピー"(または、"+\.txt$;+\.rtf$;-コピー")とします。

ファイルのフィルタと同じように、フォルダのフィルタをCreateZipメソッドの5番目のパラメータとして指定することもできます。

フィルタをNoting(C#では、null)または空の文字列("")にすると、すべてのファイルまたはフォルダが対象になります。

FastZipクラスで展開する

ZIP書庫を展開するには、ExtractZipメソッドを使います。

以下に例を示します。ここでは、ZIP書庫"C:\test.zip"をフォルダ"C:\temp"に展開しています。

VB.NET
コードを隠すコードを選択
'展開するZIP書庫のパス 
Dim zipFileName As String = "C:\test.zip"
'展開したファイルを保存するフォルダ(存在しないと作成される) 
Dim targetDirectory As String = "C:\temp"
'展開するファイルのフィルタ 
Dim fileFilter As String = ""

'FastZipオブジェクトの作成 
Dim fastZip As New ICSharpCode.SharpZipLib.Zip.FastZip()
'属性を復元するか。デフォルトはfalse 
fastZip.RestoreAttributesOnExtract = True
'ファイル日時を復元するか。デフォルトはfalse 
fastZip.RestoreDateTimeOnExtract = True
'空のフォルダも作成するか。デフォルトはfalse 
fastZip.CreateEmptyDirectories = True

'パスワードが設定されているとき 
'パスワードが設定されている書庫をパスワードを指定せずに展開しようとすると、 
' 例外ZipExceptionがスローされる 
'fastZip.Password = "password"

'ZIP書庫を展開する 
fastZip.ExtractZip(zipFileName, targetDirectory, fileFilter)
C#
コードを隠すコードを選択
//展開するZIP書庫のパス
string zipFileName = @"C:\test.zip";
//展開したファイルを保存するフォルダ(存在しないと作成される)
string targetDirectory = @"C:\temp";
//展開するファイルのフィルタ
string fileFilter = "";

//FastZipオブジェクトの作成
ICSharpCode.SharpZipLib.Zip.FastZip fastZip =
    new ICSharpCode.SharpZipLib.Zip.FastZip();
//属性を復元するか。デフォルトはfalse
fastZip.RestoreAttributesOnExtract = true;
//ファイル日時を復元するか。デフォルトはfalse
fastZip.RestoreDateTimeOnExtract = true;
//空のフォルダも作成するか。デフォルトはfalse
fastZip.CreateEmptyDirectories = true;

//パスワードが設定されているとき
//パスワードが設定されている書庫をパスワードを指定せずに展開しようとすると、
// 例外ZipExceptionがスローされる
//fastZip.Password = "password";

//ZIP書庫を展開する
fastZip.ExtractZip(zipFileName, targetDirectory, fileFilter);

展開するファイルがすでに存在する時の動作を変更する

上記の例では、展開するファイルがすでに存在していると、上書きされます。これを変更するには、ExtractZipメソッドの別のオーバーロードを使用します。

絶対に上書きしないようにするには、ExtractZipメソッドの3番目のパラメータをFastZip.Overwrite.Neverにして、4番目のパラメータをNoting(C#では、null)にします。

さらに、ユーザーに問い合わせるなどのように、状況に応じて上書きするかを決めるようにすることもできます。この場合、3番目のパラメータをFastZip.Overwrite.Promptとし、4番目のパラメータにFastZip.ConfirmOverwriteDelegateデリゲートを指定します。

このExtractZipメソッドのオーバーロードを使用する場合は、5番目のパラメータに展開するファイルのフィルタを、6番目のパラメータに展開するフォルダのフィルタを、7番目のパラメータにファイル日時を復元するかを指定します。この7番目のパラメータは、FastZip.RestoreDateTimeOnExtractプロパティと同じ意味ではないかと思われます。

以下の例では、ZIP書庫を展開するとき、ファイルを上書きする必要があるときはメッセージボックスを表示してユーザーに問い合わせるようにしています。

VB.NET
コードを隠すコードを選択
'Button1のClickイベントハンドラ 
Private Sub Button1_Click(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles Button1.Click
    '展開するZIP書庫のパス 
    Dim zipFileName As String = "C:\test.zip"
    '展開したファイルを保存するフォルダ(存在しないと作成される) 
    Dim targetDirectory As String = "C:\temp"
    '展開するファイルのフィルタ 
    Dim fileFilter As String = ""
    '展開するフォルダのフィルタ 
    Dim directoryFilter As String = ""

    'FastZipオブジェクトの作成 
    Dim fastZip As New ICSharpCode.SharpZipLib.Zip.FastZip()

    'ZIP書庫を展開する 
    fastZip.ExtractZip(zipFileName, _
        targetDirectory, _
        ICSharpCode.SharpZipLib.Zip.FastZip.Overwrite.Prompt, _
        New ICSharpCode.SharpZipLib.Zip.FastZip.ConfirmOverwriteDelegate( _
            AddressOf FastZipConfirmOverwrite), _
        fileFilter, _
        directoryFilter, _
        fastZip.RestoreDateTimeOnExtract)
End Sub

'上書きするときはtrueを返す 
Private Function FastZipConfirmOverwrite(ByVal file As String) As Boolean
    Return System.Windows.Forms.MessageBox.Show( _
        file & vbCrLf & "を上書きしますか?", _
        "上書きの確認", _
        System.Windows.Forms.MessageBoxButtons.YesNo) = DialogResult.Yes
End Function
C#
コードを隠すコードを選択
private void Button1_Click(object sender, EventArgs e)
{
    //展開するZIP書庫のパス
    string zipFileName = @"C:\test.zip";
    //展開したファイルを保存するフォルダ(存在しないと作成される)
    string targetDirectory = @"C:\temp";
    //展開するファイルのフィルタ
    string fileFilter = "";
    //展開するフォルダのフィルタ
    string directoryFilter = "";

    //FastZipオブジェクトの作成
    ICSharpCode.SharpZipLib.Zip.FastZip fastZip =
        new ICSharpCode.SharpZipLib.Zip.FastZip();

    //ZIP書庫を展開する
    fastZip.ExtractZip(zipFileName,
        targetDirectory,
        ICSharpCode.SharpZipLib.Zip.FastZip.Overwrite.Prompt,
        new ICSharpCode.SharpZipLib.Zip.FastZip.ConfirmOverwriteDelegate(
            FastZipConfirmOverwrite),
        fileFilter,
        directoryFilter,
        fastZip.RestoreDateTimeOnExtract);
}

//上書きするときはtrueを返す
private bool FastZipConfirmOverwrite(string file)
{
    return System.Windows.Forms.MessageBox.Show(
        file + "\nを上書きしますか?",
        "上書きの確認",
        System.Windows.Forms.MessageBoxButtons.YesNo) == DialogResult.Yes;
}

補足:読み取り専用ファイルを上書きしようとすると、例外UnauthorizedAccessExceptionがスローされます。以下に紹介するFastZip.FileFailureプロパティを使用すると、エラーを出さないようにすることができます。

FastZipクラスで圧縮、展開する時、進行状況を表示する

FastZipクラスでは、ファイルを圧縮(あるいは展開)する時に、その進行状況や、エラーが発生したことをコールバックメソッドで知ることができます。そのためには、FastZipEventsオブジェクトを作成し、適当なフィールドにコールバックメソッドを設定し、FastZipのコンストラクタにパラメータとして渡します。

FastZipEventsクラスには以下のようなフィールドが用意されており、コールバックメソッドを設定することができます。

フィールド名説明
ProcessFile1つのファイルの圧縮または展開を始める時に呼び出される。ScanEventArgsのNameプロパティは処理するファイルのフルパスになる。ContinueRunningプロパティをfalseにすると、これ以降のすべての処理がキャンセルされる。
Progress1つのファイルの圧縮または展開中に呼び出される。ScanEventArgsのPercentCompleteプロパティは進行状況のパーセント、Processedプロパティは処理したバイト数、Targetプロパティはファイルのバイト数となる。
CompletedFile1つのファイルの圧縮または展開が完了した時に呼び出される。
ProcessDirectory1つのフォルダを作成した時に呼び出される。(空のフォルダを圧縮または展開するときだけ呼び出される?)DirectoryEventArgsのContinueRunningプロパティをfalseにすると、これ以降のすべての処理がキャンセルされる。
FileFailureファイルの圧縮または展開に失敗した時に呼び出される。これが設定されていると、ファイルの処理に失敗してもExtractZipが例外をスローしない。ScanFailureEventArgsのContinueRunningプロパティをfalseにすると、これ以降のすべての処理がキャンセルされる。
DirectoryFailureフォルダの圧縮または展開に失敗した時に呼び出される。これが設定されていると、フォルダの処理に失敗してもExtractZipが例外をスローしない。ScanFailureEventArgsのContinueRunningプロパティをfalseにすると、これ以降のすべての処理がキャンセルされる。

これらすべてのコールバックメソッドを使用して書庫を作成する例を示します。

VB.NET
コードを隠すコードを選択
'Button1のClickイベントハンドラ 
Private Sub Button1_Click(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles Button1.Click
    '作成するZIP書庫のパス 
    Dim zipFileName As String = "C:\test.zip"
    '圧縮するフォルダのパス 
    Dim sourceDirectory As String = "C:\doc"
    'サブディレクトリも圧縮するかどうか 
    Dim recurse As Boolean = True

    'FastZipEventsの作成 
    Dim fastZipEvents As New ICSharpCode.SharpZipLib.Zip.FastZipEvents()
    fastZipEvents.CompletedFile = _
        New ICSharpCode.SharpZipLib.Core.CompletedFileHandler( _
            AddressOf CompletedFile)
    fastZipEvents.DirectoryFailure = _
        New ICSharpCode.SharpZipLib.Core.DirectoryFailureHandler( _
            AddressOf DirectoryFailure)
    fastZipEvents.FileFailure = _
        New ICSharpCode.SharpZipLib.Core.FileFailureHandler( _
            AddressOf FileFailure)
    fastZipEvents.ProcessDirectory = _
        New ICSharpCode.SharpZipLib.Core.ProcessDirectoryHandler( _
            AddressOf ProcessDirectory)
    fastZipEvents.ProcessFile = _
        New ICSharpCode.SharpZipLib.Core.ProcessFileHandler( _
            AddressOf ProcessFile)
    fastZipEvents.Progress = _
        New ICSharpCode.SharpZipLib.Core.ProgressHandler( _
            AddressOf Progress)

    'FastZipオブジェクトの作成 
    Dim fastZip As New ICSharpCode.SharpZipLib.Zip.FastZip(fastZipEvents)
    '空のフォルダも書庫に入れるか 
    fastZip.CreateEmptyDirectories = True

    '圧縮してZIP書庫を作成 
    fastZip.CreateZip(zipFileName, sourceDirectory, recurse, Nothing, Nothing)
End Sub

'1つのファイルの圧縮、展開を始める時 
Private Sub ProcessFile(ByVal sender As Object, _
        ByVal e As ICSharpCode.SharpZipLib.Core.ScanEventArgs)
    Console.WriteLine("""{0}""の処理を開始", e.Name)
End Sub

'1つのファイルの圧縮、展開の進行状況 
Private Sub Progress(ByVal sender As Object, _
        ByVal e As ICSharpCode.SharpZipLib.Core.ProgressEventArgs)
    Console.WriteLine("{0}%({1}/{2})", e.PercentComplete, e.Processed, e.Target)
End Sub

'1つのファイルの圧縮、展開が完了した時 
Private Sub CompletedFile(ByVal sender As Object, _
        ByVal e As ICSharpCode.SharpZipLib.Core.ScanEventArgs)
    Console.WriteLine("""{0}""の処理が完了", e.Name)
End Sub

'1つのフォルダの圧縮、展開が完了した時 
Private Sub ProcessDirectory(ByVal sender As Object, _
        ByVal e As ICSharpCode.SharpZipLib.Core.DirectoryEventArgs)
    Console.WriteLine("フォルダ""{0}""の処理を開始", e.Name)
End Sub

'ファイルの圧縮、展開でエラーが発生した時 
Private Sub FileFailure(ByVal sender As Object, _
        ByVal e As ICSharpCode.SharpZipLib.Core.ScanFailureEventArgs)
    'e.ContinueRunning = false; 
    'とすると、以降の処理をキャンセル 
    Console.WriteLine("""{0}""の処理中にエラー({1})が発生", _
                      e.Name, e.Exception.Message)
End Sub

'フォルダの圧縮、展開でエラーが発生した時 
Private Sub DirectoryFailure(ByVal sender As Object, _
        ByVal e As ICSharpCode.SharpZipLib.Core.ScanFailureEventArgs)
    Console.WriteLine("フォルダ""{0}""の処理中にエラー({1})が発生", _
                      e.Name, e.Exception.Message)
End Sub
C#
コードを隠すコードを選択
//Button1のClickイベントハンドラ
private void Button1_Click(object sender, EventArgs e)
{
    //作成するZIP書庫のパス
    string zipFileName = @"C:\test.zip";
    //圧縮するフォルダのパス
    string sourceDirectory = @"C:\doc";
    //サブディレクトリも圧縮するかどうか
    bool recurse = true;

    //FastZipEventsの作成
    ICSharpCode.SharpZipLib.Zip.FastZipEvents fastZipEvents =
        new ICSharpCode.SharpZipLib.Zip.FastZipEvents();
    fastZipEvents.CompletedFile =
        new ICSharpCode.SharpZipLib.Core.CompletedFileHandler(CompletedFile);
    fastZipEvents.DirectoryFailure =
        new ICSharpCode.SharpZipLib.Core.DirectoryFailureHandler(DirectoryFailure);
    fastZipEvents.FileFailure =
        new ICSharpCode.SharpZipLib.Core.FileFailureHandler(FileFailure);
    fastZipEvents.ProcessDirectory =
        new ICSharpCode.SharpZipLib.Core.ProcessDirectoryHandler(ProcessDirectory);
    fastZipEvents.ProcessFile =
        new ICSharpCode.SharpZipLib.Core.ProcessFileHandler(ProcessFile);
    fastZipEvents.Progress =
        new ICSharpCode.SharpZipLib.Core.ProgressHandler(Progress);

    //FastZipオブジェクトの作成
    ICSharpCode.SharpZipLib.Zip.FastZip fastZip =
        new ICSharpCode.SharpZipLib.Zip.FastZip(fastZipEvents);
    //空のフォルダも書庫に入れるか
    fastZip.CreateEmptyDirectories = true;

    //圧縮してZIP書庫を作成
    fastZip.CreateZip(zipFileName, sourceDirectory, recurse, null, null);
}

//1つのファイルの圧縮、展開を始める時
private void ProcessFile(Object sender,
    ICSharpCode.SharpZipLib.Core.ScanEventArgs e)
{
    Console.WriteLine("\"{0}\"の処理を開始", e.Name);
}

//1つのファイルの圧縮、展開の進行状況
private void Progress(Object sender,
    ICSharpCode.SharpZipLib.Core.ProgressEventArgs e)
{
    Console.WriteLine("{0}%({1}/{2})",
        e.PercentComplete, e.Processed, e.Target);
}

//1つのファイルの圧縮、展開が完了した時
private void CompletedFile(Object sender,
    ICSharpCode.SharpZipLib.Core.ScanEventArgs e)
{
    Console.WriteLine("\"{0}\"の処理が完了", e.Name);
}

//1つのフォルダの圧縮、展開が完了した時
private void ProcessDirectory(Object sender,
    ICSharpCode.SharpZipLib.Core.DirectoryEventArgs e)
{
    Console.WriteLine("フォルダ\"{0}\"の処理を開始", e.Name);

}

//ファイルの圧縮、展開でエラーが発生した時
private void FileFailure(Object sender,
    ICSharpCode.SharpZipLib.Core.ScanFailureEventArgs e)
{
    Console.WriteLine("\"{0}\"の処理中にエラー({1})が発生",
        e.Name, e.Exception.Message);

    //e.ContinueRunning = false;
    //とすると、以降の処理をキャンセル
}

//フォルダの圧縮、展開でエラーが発生した時
private void DirectoryFailure(Object sender,
    ICSharpCode.SharpZipLib.Core.ScanFailureEventArgs e)
{
    Console.WriteLine("フォルダ\"{0}\"の処理中にエラー({1})が発生",
        e.Name, e.Exception.Message);
}

書庫内のファイルを列挙する

ここからは、FastZipクラスを使用しない方法です。

まずは、ZIP書庫内のファイルやディレクトリ(エントリ)を列挙する方法を紹介します。

ZipInputStreamクラスを使用する

ZipInputStreamクラスを使用して、ZIP書庫内のエントリを列挙することができます。エントリ情報は、GetNextEntryメソッドを使ってZipEntryオブジェクトとして取得します。

以下の例では、"C:\test.zip"内のエントリの情報を列挙しています。

VB.NET
コードを隠すコードを選択
'開くZIP書庫のパス
Dim zipPath As String = "C:\test.zip"

'ZIP書庫を読み込む 
Dim fs As New System.IO.FileStream( _
    zipPath, _
    System.IO.FileMode.Open, _
    System.IO.FileAccess.Read)
'ZipInputStreamオブジェクトの作成 
Dim zis As New ICSharpCode.SharpZipLib.Zip.ZipInputStream(fs)

'ZIP内のエントリを列挙
Dim ze As ICSharpCode.SharpZipLib.Zip.ZipEntry
While True
    'ZipEntryを取得
    ze = zis.GetNextEntry()
    If ze Is Nothing Then
        Exit While
    End If
    '情報を表示する 
    If ze.IsFile Then
        'ファイルのとき 
        Console.WriteLine("名前 : {0}", ze.Name)
        Console.WriteLine("サイズ : {0} bytes", ze.Size)
        Console.WriteLine("格納サイズ : {0} bytes", ze.CompressedSize)
        Console.WriteLine("圧縮方法 : {0}", ze.CompressionMethod)
        Console.WriteLine("CRC : {0:X}", ze.Crc)
        Console.WriteLine("日時 : {0}", ze.DateTime)
        Console.WriteLine();
    ElseIf ze.IsDirectory Then
        'ディレクトリのとき 
        Console.WriteLine("ディレクトリ名 : {0}", ze.Name)
        Console.WriteLine("日時 : {0}", ze.DateTime)
        Console.WriteLine()
    End If
End While

'閉じる 
zis.Close()
fs.Close()
C#
コードを隠すコードを選択
//開くZIP書庫のパス
string zipPath = @"C:\test.zip";

//ZIP書庫を読み込む
System.IO.FileStream fs = new System.IO.FileStream(
    zipPath,
    System.IO.FileMode.Open,
    System.IO.FileAccess.Read);
//ZipInputStreamオブジェクトの作成
ICSharpCode.SharpZipLib.Zip.ZipInputStream zis =
    new ICSharpCode.SharpZipLib.Zip.ZipInputStream(fs);

//ZIP内のエントリを列挙
ICSharpCode.SharpZipLib.Zip.ZipEntry ze;
//ZipEntryを取得
while ((ze = zis.GetNextEntry()) != null)
{
    //情報を表示する
    if (ze.IsFile)
    {
        //ファイルのとき
        Console.WriteLine("名前 : {0}", ze.Name);
        Console.WriteLine("サイズ : {0} bytes", ze.Size);
        Console.WriteLine("格納サイズ : {0} bytes", ze.CompressedSize);
        Console.WriteLine("圧縮方法 : {0}", ze.CompressionMethod);
        Console.WriteLine("CRC : {0:X}", ze.Crc);
        Console.WriteLine("日時 : {0}", ze.DateTime);
        Console.WriteLine();
    }
    else if (ze.IsDirectory)
    {
        //ディレクトリのとき
        Console.WriteLine("ディレクトリ名 : {0}", ze.Name);
        Console.WriteLine("日時 : {0}", ze.DateTime);
        Console.WriteLine();
    }
}

//閉じる
zis.Close();
fs.Close();

ZipFileクラスを使用する

ZipFileクラスを使用することもできます。ZipFileクラスではFor EachでZipEntryを取得できますので、より分かりやすいかもしれません。

VB.NET
コードを隠すコードを選択
'開くZIP書庫 
Dim zipPath As String = "C:\test.zip"

'ZipFileオブジェクトの作成 
Dim zf As New ICSharpCode.SharpZipLib.Zip.ZipFile(zipPath)

'ZIP内のエントリを列挙
Dim ze As ICSharpCode.SharpZipLib.Zip.ZipEntry
For Each ze In zf
    '情報を表示する 
    If ze.IsFile Then
        'ファイルのとき 
        Console.WriteLine("名前 : {0}", ze.Name)
    ElseIf ze.IsDirectory Then
        'ディレクトリのとき 
        Console.WriteLine("ディレクトリ名 : {0}", ze.Name)
    End If
Next
C#
コードを隠すコードを選択
//開くZIP書庫
string zipPath = @"C:\test.zip";

//ZipFileオブジェクトの作成
ICSharpCode.SharpZipLib.Zip.ZipFile zf =
    new ICSharpCode.SharpZipLib.Zip.ZipFile(zipPath);

//ZIP内のエントリを列挙
foreach (ICSharpCode.SharpZipLib.Zip.ZipEntry ze in zf)
{
    //情報を表示する
    if (ze.IsFile)
    {
        //ファイルのとき
        Console.WriteLine("名前 : {0}", ze.Name);
    }
    else if (ze.IsDirectory)
    {
        //ディレクトリのとき
        Console.WriteLine("ディレクトリ名 : {0}", ze.Name);
    }
}

//閉じる
zf.Close();

ZipFileクラスはZipInputStreamクラスと違い、コメントを取得できます。ZIP書庫のコメントはZipFile.ZipFileCommentプロパティで、エントリのコメントはZipEntry.Commentプロパティで取得できます。ZipInputStreamクラスではZipEntry.Commentプロパティでコメントを取得することができません。

なおコメントの設定は、ZipFileクラスでもZipOutputStreamクラスでもできます。ZIP書庫のコメントはSetCommentメソッドで、エントリのコメントはZipEntry.Commentプロパティでできます。

書庫内のファイルを展開する

展開の方法も、ZipInputStreamクラスを使った方法と、ZipFileクラスを使った方法を紹介します。

ZipInputStreamクラスを使用する

ZipInputStreamクラスを使用して、書庫内のすべてのエントリを展開する例を示します。先のエントリを列挙する方法と同じやり方で展開するエントリを探し、ZipInputStream.Readメソッドでその内容を読み込みます。

VB.NET
コードを隠すコードを選択
'展開するZIP書庫のパス
Dim zipPath As String = "C:\test.zip"
'展開先のフォルダのパス
Dim extractDir As String = "C:\temp"

'ZIP書庫を読み込む 
Dim fs As New System.IO.FileStream( _
    zipPath, _
    System.IO.FileMode.Open, _
    System.IO.FileAccess.Read)
'ZipInputStreamオブジェクトの作成 
Dim zis As New ICSharpCode.SharpZipLib.Zip.ZipInputStream(fs)

'パスワードが設定されているときは指定する 
'zis.Password = "pass"

'ZIP内のエントリを列挙 
Dim ze As ICSharpCode.SharpZipLib.Zip.ZipEntry
While True
    'ZipEntryを取得
    ze = zis.GetNextEntry()
    If ze Is Nothing Then
        Exit While
    End If
    If Not ze.IsDirectory Then
        '展開先のファイル名を決定 
        Dim fileName As String = System.IO.Path.GetFileName(ze.Name)
        '展開先のフォルダを決定 
        Dim destDir As String = System.IO.Path.Combine( _
            extractDir, System.IO.Path.GetDirectoryName(ze.Name))
        System.IO.Directory.CreateDirectory(destDir)
        '展開先のファイルのフルパスを決定 
        Dim destPath As String = System.IO.Path.Combine(destDir, fileName)

        '書き込み先のファイルを開く
        Dim writer As New System.IO.FileStream(destPath, _
            System.IO.FileMode.Create, System.IO.FileAccess.Write)
        '展開するファイルを読み込む
        Dim buffer As Byte() = New Byte(2047) {}
        Dim len As Integer
        While True
            len = zis.Read(buffer, 0, buffer.Length)
            If len = 0 Then
                Exit While
            End If
            'ファイルに書き込む
            writer.Write(buffer, 0, len)
        End While
        '閉じる 
        writer.Close()
    Else
        'フォルダのとき 
        '作成するフォルダのフルパスを決定 
        Dim dirPath As String = System.IO.Path.Combine( _
            extractDir, System.IO.Path.GetDirectoryName(ze.Name))
        'フォルダを作成 
        System.IO.Directory.CreateDirectory(dirPath)
    End If
End While

'閉じる 
zis.Close()
fs.Close()
C#
コードを隠すコードを選択
//展開するZIP書庫のパス
string zipPath = @"C:\test.zip";
//展開先のフォルダのパス
string extractDir = @"C:\temp";

//ZIP書庫を読み込む 
System.IO.FileStream fs = new System.IO.FileStream(
    zipPath, System.IO.FileMode.Open,
    System.IO.FileAccess.Read);
//ZipInputStreamオブジェクトの作成
ICSharpCode.SharpZipLib.Zip.ZipInputStream zis =
    new ICSharpCode.SharpZipLib.Zip.ZipInputStream(fs);

//パスワードが設定されているときは指定する
//zis.Password = "pass";

//ZIP内のエントリを列挙
ICSharpCode.SharpZipLib.Zip.ZipEntry ze;
//ZipEntryを取得
while ((ze = zis.GetNextEntry()) != null)
{
    if (!ze.IsDirectory)
    {
        //展開先のファイル名を決定
        string fileName = System.IO.Path.GetFileName(ze.Name);
        //展開先のフォルダを決定
        string destDir = System.IO.Path.Combine(extractDir,
            System.IO.Path.GetDirectoryName(ze.Name));
        System.IO.Directory.CreateDirectory(destDir);
        //展開先のファイルのフルパスを決定
        string destPath = System.IO.Path.Combine(destDir, fileName);

        //書き込み先のファイルを開く
        System.IO.FileStream writer = new System.IO.FileStream(
            destPath, System.IO.FileMode.Create,
            System.IO.FileAccess.Write);
        //展開するファイルを読み込む
        byte[] buffer = new byte[2048];
        int len;
        while ((len = zis.Read(buffer, 0, buffer.Length)) > 0)
        {
            //ファイルに書き込む
            writer.Write(buffer, 0, len);
        }
        //閉じる
        writer.Close();
    }
    else
    {
        //フォルダのとき
        //作成するフォルダのフルパスを決定
        string dirPath = System.IO.Path.Combine(extractDir,
            System.IO.Path.GetDirectoryName(ze.Name));
        //フォルダを作成
        System.IO.Directory.CreateDirectory(dirPath);
    }
}

//閉じる
zis.Close();
fs.Close();

ZipFileクラスを使用する

ZipFileクラスを使った方法では、指定したエントリ(ファイル)のみを展開する例を示します。もちろんすべてのエントリを展開することもできます。GetEntryメソッドで展開するZipEntryを探し、GetInputStreamメソッドでエントリの内容を読み込むStreamを取得します。

VB.NET
コードを隠すコードを選択
'展開するZIP書庫のパス 
Dim zipPath As String = "C:\test.zip"
'展開先のフォルダのパス 
Dim extractDir As String = "C:\temp"
'展開するエントリ 
Dim extractFile As String = "readme.txt"

'ZipFileオブジェクトの作成 
Dim zf As New ICSharpCode.SharpZipLib.Zip.ZipFile(zipPath)

'展開するエントリを探す 
Dim ze As ICSharpCode.SharpZipLib.Zip.ZipEntry = zf.GetEntry(extractFile)

If Not ze Is Nothing Then
    '展開先のファイル名を決定 
    Dim fileName As String = System.IO.Path.GetFileName(ze.Name)
    '展開先のフォルダを決定 
    Dim destDir As String = System.IO.Path.Combine( _
        extractDir, System.IO.Path.GetDirectoryName(ze.Name))
    System.IO.Directory.CreateDirectory(destDir)
    '展開先のファイルのフルパスを決定 
    Dim destPath As String = System.IO.Path.Combine(destDir, fileName)

    '展開するZIPエントリのStreamを取得 
    Dim reader As System.IO.Stream = zf.GetInputStream(ze)
    '書き込み先のファイルのStreamを取得 
    Dim writer As New System.IO.FileStream(destPath, _
        System.IO.FileMode.Create, System.IO.FileAccess.Write)
    'ファイルに書き込む 
    Dim buffer As Byte() = New Byte(2047) {}
    Dim len As Integer
    While True
        len = reader.Read(buffer, 0, buffer.Length)
        If len = 0 Then
            Exit While
        End If
        writer.Write(buffer, 0, len)
    End While

    '閉じる 
    writer.Close()
    reader.Close()
End If

'閉じる 
zf.Close()
C#
コードを隠すコードを選択
//展開するZIP書庫のパス
string zipPath = @"C:\test.zip";
//展開先のフォルダのパス
string extractDir = @"C:\temp";
//展開するエントリ
string extractFile = "readme.txt";

//ZipFileオブジェクトの作成
ICSharpCode.SharpZipLib.Zip.ZipFile zf =
    new ICSharpCode.SharpZipLib.Zip.ZipFile(zipPath);

//展開するエントリを探す
ICSharpCode.SharpZipLib.Zip.ZipEntry ze = zf.GetEntry(extractFile);

if (ze != null)
{
    //展開先のファイル名を決定
    string fileName = System.IO.Path.GetFileName(ze.Name);
    //展開先のフォルダを決定
    string destDir = System.IO.Path.Combine(extractDir,
        System.IO.Path.GetDirectoryName(ze.Name));
    System.IO.Directory.CreateDirectory(destDir);
    //展開先のファイルのフルパスを決定
    string destPath = System.IO.Path.Combine(destDir, fileName);

    //展開するZIPエントリのStreamを取得 
    System.IO.Stream reader = zf.GetInputStream(ze);
    //書き込み先のファイルのStreamを取得
    System.IO.FileStream writer = new System.IO.FileStream(
        destPath, System.IO.FileMode.Create,
        System.IO.FileAccess.Write);
    //ファイルに書き込む
    byte[] buffer = new byte[2048];
    int len;
    while ((len = reader.Read(buffer, 0, buffer.Length)) > 0)
    {
        writer.Write(buffer, 0, len);
    }

    //閉じる
    writer.Close();
    reader.Close();
}

//閉じる
zf.Close();

書庫内のファイルを閲覧する

書庫内のファイルの内容を、ファイルとして展開することなく閲覧する方法は、上記のファイルを展開する方法とほぼ同じです。違いは、データをファイルに書き込まずに文字列に変換して表示する点だけです。

以下にZipFileクラスを使って書庫内の"readme.txt"ファイルの内容を表示する例を示します。

VB.NET
コードを隠すコードを選択
'ZIP書庫のパス
Dim zipPath As String = "C:\test.zip"
'閲覧するエントリ 
Dim extractFile As String = "readme.txt"

'ZipFileオブジェクトの作成 
Dim zf As New ICSharpCode.SharpZipLib.Zip.ZipFile(zipPath)

'展開するエントリを探す 
Dim ze As ICSharpCode.SharpZipLib.Zip.ZipEntry = zf.GetEntry(extractFile)

If Not ze Is Nothing Then
    '閲覧するZIPエントリのStreamを取得 
    Dim reader As System.IO.Stream = zf.GetInputStream(ze)
    '文字コードを指定してStreamReaderを作成 
    Dim sr As New System.IO.StreamReader(reader, _
        System.Text.Encoding.GetEncoding("Shift_JIS"))
    '文字列を取得して、表示 
    Console.Write(sr.ReadToEnd())

    '閉じる 
    sr.Close()
    reader.Close()
End If

'閉じる 
zf.Close()
C#
コードを隠すコードを選択
//ZIP書庫のパス
string zipPath = @"C:\test.zip";
//閲覧するエントリ
string extractFile = "readme.txt";

//ZipFileオブジェクトの作成
ICSharpCode.SharpZipLib.Zip.ZipFile zf =
    new ICSharpCode.SharpZipLib.Zip.ZipFile(zipPath);

//展開するエントリを探す
ICSharpCode.SharpZipLib.Zip.ZipEntry ze = zf.GetEntry(extractFile);

if (ze != null)
{
    //閲覧するZIPエントリのStreamを取得
    System.IO.Stream reader = zf.GetInputStream(ze);
    //文字コードを指定してStreamReaderを作成
    System.IO.StreamReader sr = new System.IO.StreamReader(
        reader, System.Text.Encoding.GetEncoding("Shift_JIS"));
    //文字列を取得して、表示
    Console.Write(sr.ReadToEnd());

    //閉じる
    sr.Close();
    reader.Close();
}

//閉じる
zf.Close();

圧縮(書庫を作成)する

ZipOutputStreamクラスを使用する

ZipOutputStreamクラスを使って、ZIP書庫を作成することができます。ZipEntryを作成してPutNextEntryメソッドに渡してから、Writeメソッドで書き込みます。

指定したフォルダ以下のファイルを圧縮してZIP書庫を作成する例を以下に示します。

VB.NET
コードを隠すコードを選択
'作成するZIP書庫のパス
Dim zipPath As String = "C:\test.zip"
'圧縮するファイルのあるフォルダのパス 
Dim zipFolder As String = "C:\doc"

'書き込むZIP書庫のStream 
Dim writer As New System.IO.FileStream(zipPath, _
    System.IO.FileMode.Create, System.IO.FileAccess.Write)
'ZipOutputStreamを作成 
Dim zos As New ICSharpCode.SharpZipLib.Zip.ZipOutputStream(writer)

'圧縮レベルを設定する。0は圧縮しない。9は最高圧縮。 
zos.SetLevel(9)
'パスワードを設定する 
'zos.Password = "pass"

'圧縮するフォルダにあるファイルを取得 
Dim files As String() = System.IO.Directory.GetFiles(zipFolder, _
    "*", System.IO.SearchOption.AllDirectories)

'ファイル名からエントリ名を決定するためにZipNameTransformを使用する 
'zipFolderを基にした相対パスをエントリ名にする 
Dim nameTrans As New ICSharpCode.SharpZipLib.Zip.ZipNameTransform(zipFolder)

For Each file As String In files
    'ZIP内のエントリの名前を決定する 
    Dim f As String = nameTrans.TransformFile(file)

    'ZipEntryを作成 
    Dim ze As New ICSharpCode.SharpZipLib.Zip.ZipEntry(f)

    'エントリ情報を設定する。設定しなくてもよい 
    Dim fi As New System.IO.FileInfo(file)
    '時間を設定する 
    ze.DateTime = fi.LastAccessTime
    '属性を保持する 
    ze.ExternalFileAttributes = CInt(fi.Attributes)
    'サイズを設定する 
    ze.Size = fi.Length
    'エントリ名とコメントにunicode UTF8を使う
    'ze.IsUnicodeText = True

    '新しいエントリの追加を開始 
    zos.PutNextEntry(ze)

    '圧縮するファイルを読み込む 
    Dim fs As New System.IO.FileStream(file, _
        System.IO.FileMode.Open, System.IO.FileAccess.Read)
    Dim buffer As Byte() = New Byte(2047) {}
    Dim len As Integer
    While True
        len = fs.Read(buffer, 0, buffer.Length)
        If len = 0 Then
            Exit While
        End If
        '書庫に書き込む
        zos.Write(buffer, 0, len)
    End While
    fs.Close()
Next

'閉じる 
zos.Finish()
zos.Close()
writer.Close()
C#
コードを隠すコードを選択
//作成するZIP書庫のパス
string zipPath = @"C:\test.zip";
//圧縮するファイルのあるフォルダのパス
string zipFolder = @"C:\doc";

//書き込むZIP書庫のStream
System.IO.FileStream writer = new System.IO.FileStream(
    zipPath, System.IO.FileMode.Create,
    System.IO.FileAccess.Write);
//ZipOutputStreamを作成
ICSharpCode.SharpZipLib.Zip.ZipOutputStream zos =
    new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(writer);

//圧縮レベルを設定する。0は圧縮しない。9は最高圧縮。
zos.SetLevel(9);
//パスワードを設定する
//zos.Password = "pass";

//圧縮するフォルダにあるファイルを取得
string[] files = System.IO.Directory.GetFiles(zipFolder,
    "*", System.IO.SearchOption.AllDirectories);

//ファイル名からエントリ名を決定するためにZipNameTransformを使用する
//zipFolderを基にした相対パスをエントリ名にする
ICSharpCode.SharpZipLib.Zip.ZipNameTransform nameTrans =
    new ICSharpCode.SharpZipLib.Zip.ZipNameTransform(zipFolder);

foreach (string file in files)
{
    //ZIP内のエントリの名前を決定する
    string f = nameTrans.TransformFile(file);

    //ZipEntryを作成
    ICSharpCode.SharpZipLib.Zip.ZipEntry ze =
        new ICSharpCode.SharpZipLib.Zip.ZipEntry(f);

    //エントリ情報を設定する。設定しなくてもよい
    System.IO.FileInfo fi = new System.IO.FileInfo(file);
    //時間を設定する
    ze.DateTime = fi.LastAccessTime;
    //属性を保持する
    ze.ExternalFileAttributes = (int)fi.Attributes;
    //サイズを設定する
    ze.Size = fi.Length;
    //エントリ名とコメントにunicode UTF8を使う
    //ze.IsUnicodeText = true;

    //新しいエントリの追加を開始
    zos.PutNextEntry(ze);

    //圧縮するファイルを読み込む
    System.IO.FileStream fs = new System.IO.FileStream(
        file,
        System.IO.FileMode.Open,
        System.IO.FileAccess.Read);
    byte[] buffer = new byte[2048];
    int len;
    while ((len = fs.Read(buffer, 0, buffer.Length)) > 0)
    {
        //書庫に書き込む
        zos.Write(buffer, 0, len);
    }
    fs.Close();
}

//閉じる
zos.Finish();
zos.Close();
writer.Close();

補足:以前紹介していたサンプルではZipEntry.Crcを設定していましたが、最近のバージョンの#ziplibではこのようにしてZIP書庫を作成すると、一般的なアーカイバでこの書庫を開いたときにヘッダが壊れていると判断されてしまいます。

ZipFileクラスを使用する

ZipFileクラスを使ってZIP書庫を作成するには、ZipFile.CreateメソッドでZipFileオブジェクトを作成し、Addメソッドでエントリを追加します。先のZipOutputStreamの例と同じようにAddメソッドにZipEntryを指定することもできますが、ファイルのパスだけ、あるいはファイルのパスとエントリ名だけを指定することもできます。以下の例では、ファイルのパスとエントリ名を指定しています。

VB.NET
コードを隠すコードを選択
'作成するZIP書庫のパス
Dim zipPath As String = "C:\test.zip"
'圧縮するファイルのあるフォルダのパス
Dim zipFolder As String = "C:\doc"

'ZipFileオブジェクトの作成 
Dim zf As ICSharpCode.SharpZipLib.Zip.ZipFile = _
    ICSharpCode.SharpZipLib.Zip.ZipFile.Create(zipPath)

'圧縮するフォルダにあるファイルを取得 
Dim files As String() = System.IO.Directory.GetFiles(zipFolder, _
    "*", System.IO.SearchOption.AllDirectories)

'ファイル名からエントリ名を決定するためにZipNameTransformを使用する 
Dim nameTrans As New ICSharpCode.SharpZipLib.Zip.ZipNameTransform(zipFolder)

'ZipFileの更新を開始 
zf.BeginUpdate()

Dim file As String
For Each file In files
    'ZIP内のエントリの名前を決定する 
    Dim f As String = nameTrans.TransformFile(file)
    'ZIP書庫にファイルを追加する 
    zf.Add(file, f)
Next

'ZipFileの更新をコミット 
zf.CommitUpdate()

'閉じる 
zf.Close()
C#
コードを隠すコードを選択
//作成するZIP書庫のパス
string zipPath = @"C:\test.zip";
//圧縮するファイルのあるフォルダのパス
string zipFolder = @"C:\doc";

//ZipFileオブジェクトの作成
ICSharpCode.SharpZipLib.Zip.ZipFile zf =
    ICSharpCode.SharpZipLib.Zip.ZipFile.Create(zipPath);

//圧縮するフォルダにあるファイルを取得
string[] files = System.IO.Directory.GetFiles(zipFolder,
    "*", System.IO.SearchOption.AllDirectories);

//ファイル名からエントリ名を決定するためにZipNameTransformを使用する
ICSharpCode.SharpZipLib.Zip.ZipNameTransform nameTrans =
    new ICSharpCode.SharpZipLib.Zip.ZipNameTransform(zipFolder);

//ZipFileの更新を開始
zf.BeginUpdate();

foreach (string file in files)
{
    //ZIP内のエントリの名前を決定する
    string f = nameTrans.TransformFile(file);
    //ZIP書庫にファイルを追加する
    zf.Add(file, f);
}

//ZipFileの更新をコミット
zf.CommitUpdate();

//閉じる
zf.Close();

書庫にファイルを追加する

ZIP書庫を作成する方法と同じように、ZipFileクラスを使用すれば、すでにあるZIP書庫にファイルを追加することも簡単です。

VB.NET
コードを隠すコードを選択
'ZIP書庫のパス
Dim zipPath As String = "C:\test.zip"
'書庫に追加するファイルのパス
Dim file As String = "C:\readme.txt"

'ZipFileオブジェクトの作成 
Dim zf As New ICSharpCode.SharpZipLib.Zip.ZipFile(zipPath)

'ZipFileの更新を開始 
zf.BeginUpdate()

'ZIP内のエントリの名前を決定する 
Dim f As String = System.IO.Path.GetFileName(file)
'ZIP書庫にファイルを追加する 
zf.Add(file, f)

'ZipFileの更新をコミット 
zf.CommitUpdate()

'閉じる 
zf.Close()
C#
コードを隠すコードを選択
//ZIP書庫のパス
string zipPath = @"C:\test.zip";
//書庫に追加するファイルのパス
string file = @"C:\readme.txt";

//ZipFileオブジェクトの作成
ICSharpCode.SharpZipLib.Zip.ZipFile zf =
    new ICSharpCode.SharpZipLib.Zip.ZipFile(zipPath);

//ZipFileの更新を開始
zf.BeginUpdate();

//ZIP内のエントリの名前を決定する 
string f = System.IO.Path.GetFileName(file);
//ZIP書庫にファイルを追加する
zf.Add(file, f);

//ZipFileの更新をコミット
zf.CommitUpdate();

//閉じる
zf.Close();

書庫からファイルを削除する

ZIP書庫からエントリを削除するには、ZipFile.Deleteメソッドを使うと簡単です。下の例ではZipFile.Deleteメソッドに削除するエントリ名を指定していますが、エントリが見つからないと例外がスローされます。削除するエントリが書庫に存在するか調べてから削除するならば、展開する方法で紹介したように、GetEntryメソッドでZipEntryオブジェクトを取得し、取得できればそのZipEntryオブジェクトをDeleteメソッドに渡すやり方もあります。

VB.NET
コードを隠すコードを選択
'ZIP書庫のパス
Dim zipPath As String = "C:\test.zip"
'削除するエントリの名前 
Dim file As String = "readme.txt"

'ZipFileオブジェクトの作成 
Dim zf As New ICSharpCode.SharpZipLib.Zip.ZipFile(zipPath)

'ZipFileの更新を開始 
zf.BeginUpdate()

'エントリを削除する 
zf.Delete(file)

'ZipFileの更新をコミット 
zf.CommitUpdate()

'閉じる 
zf.Close()
C#
コードを隠すコードを選択
//ZIP書庫のパス
string zipPath = @"C:\test.zip";
//削除するエントリの名前
string file = "readme.txt";

//ZipFileオブジェクトの作成
ICSharpCode.SharpZipLib.Zip.ZipFile zf =
    new ICSharpCode.SharpZipLib.Zip.ZipFile(zipPath);

//ZipFileの更新を開始
zf.BeginUpdate();

//エントリを削除する
zf.Delete(file);

//ZipFileの更新をコミット
zf.CommitUpdate();

//閉じる
zf.Close();

書庫をテストする

ZIP書庫をテストするには、ZipFile.TestArchiveメソッドを使います。TestArchiveメソッドにfalseを渡すとヘッダだけを調べ、trueを渡すとヘッダとCRCのチェックを行うようです。

VB.NET
コードを隠すコードを選択
'テストするZIP書庫のパス 
Dim zipPath As String = "C:\test.zip"

'ZipFileオブジェクトの作成 
Dim zf As New ICSharpCode.SharpZipLib.Zip.ZipFile(zipPath)

'テストする 
If zf.TestArchive(True) Then
    Console.WriteLine("エラーはありませんでした。")
Else
    Console.WriteLine("エラーがありました。")
End If

'閉じる 
zf.Close()
C#
コードを隠すコードを選択
//テストするZIP書庫のパス
string zipPath = @"C:\test.zip";

//ZipFileオブジェクトの作成
ICSharpCode.SharpZipLib.Zip.ZipFile zf =
    new ICSharpCode.SharpZipLib.Zip.ZipFile(zipPath);

//テストする
if (zf.TestArchive(true))
{
    Console.WriteLine("エラーはありませんでした。");
}
else
{
    Console.WriteLine("エラーがありました。");
}

//閉じる
zf.Close();

さらにTestArchiveメソッドの別のオーバーロードを使えば、テストの進行状況や、エラーの出た箇所などを知ることもできますが、ここでは省略します。

  • 履歴:
  • 2009/11/2 こちらから分離。
  • 2010/11/29 補足で紹介していたFastZipのフィルタで \\ を使ったときに思ったようにならない問題が、v0.86.0.518で修正されたことを追記。(コメントでご報告いただきました。)
  • 注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

    • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。
    • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
    • 「???を参照に追加します」の意味が分からないという方は、こちらをご覧ください。
    • Windows Vista以降でUACが有効になっていると、ファイルへの書き込みに失敗する可能性があります。詳しくは、こちらをご覧ください。
    • .NET Tipsをご利用いただく際は、注意事項をお守りください。
    共有する

    この記事への評価

    この記事へのコメント

    この記事に関するコメントを投稿するには、下のボタンをクリックしてください。投稿フォームへ移動します。通常のご質問、ご意見等は掲示板へご投稿ください。