Zip for .NET
Zip ファイルの操作
Zip for.Netチュートリアル > Zip ファイルの操作

このチュートリアルでは、次のような zip ファイルの操作方法について説明します。

最終アプリケーションは、次の図のように表示されます。

メモ: これは、C1ZipFile オブジェクトの主要な機能に注目して設計された極めて単純なアプリケーションです。配布ディスクには、より高度なバージョンも用意されています。そこでは、ドラッグ&ドロップ操作、フォルダの zip 圧縮、圧縮レベルの設定などの高度な機能がサポートされています。

手順1:メインフォームを作成します。

新しい Visual Studio プロジェクトを開始します。

  1. ツールボックスから、次のコントロールをフォームに追加します。
    • フォームの左端に並べて7個の Button コントロール(前の図を参照)。[プロパティ]ウィンドウで、各 Button コントロールに次の変更を加えます。
      Button Button.Text Property Button.Name Property
      1 Create Zip File… btnNew
      2 Open Zip File… btnOpen
      3 Add Files… btnAdd
      4 Extract Files btnExtract
      5 Remove Files btnRemove
      6 View File btnView
      7 Test Zip File btnTest
    • フォームの右側をカバーする ListView コントロール。プロパティウィンドウで、Columns プロパティの横にある省略符ボタンをクリックします。[ColumnHeader コレクションエディタ]ダイアログボックスが表示されます。

    メモ: [ColumnHeader コレクションエディタ]には、[ListView タスク]メニューの[列の編集]をクリックしてアクセスすることもできます。[ListView タスク]メニューにアクセスするには、ListView コントロールの右上隅にあるスマートタグ をクリックします。

  2. [追加]ボタンをクリックし、5つの ColumnHeader を追加したら、各列の Text プロパティをそれぞれ[ファイル]、[日付]、[サイズ]、[圧縮]、および[量]に設定します。

    [ColumnHeader コレクションエディタ]は次のようになります。


               
  3. [OK]を選択して、エディタボックスを閉じます。

    列ヘッダを表示するには、[プロパティ]ウィンドウで[表示]プロパティを[詳細]に設定するか、[ListView タスク]メニューの[表示]ドロップダウンボックスから[詳細]を選択します。


               

手順2:C1Zip アセンブリに参照を追加します。

ソリューションエクスプローラウィンドウに移動し、[参照]を右クリックし、[参照の追加]メニューオプションを選択します。リストから C1.C1Zip アセンブリを選択するか、ファイルを参照して C1.C1Zip.2.dll ファイルを探します。

[Form1.vb]タブ(C# では[Form1.cs]タブ)を選択するか、[表示]→[コード]を選択して、コードエディタを開きます。ファイルの上部に、次のディレクティブを追加します。

Visual Basic でコードを書く場合

Visual Basic
コードのコピー
Imports System.IO
Imports C1.C1Zip

C# でコードを書く場合

C#
コードのコピー
using System.IO;
using C1.C1Zip;

これで、C1Zip アセンブリと System.IO アセンブリで定義されているオブジェクトがプロジェクトに表示されます。

手順3:C1ZipFile オブジェクトを宣言します。

コードエディタに切り替えて、次のデータメンバ宣言を入力するかコピーします。

Visual Basic でコードを書く場合

Visual Basic
コードのコピー
Private m_Zip As C1ZipFile

C# でコードを書く場合

C#
コードのコピー
private m_Zip As C1ZipFile;

これは、このアプリケーションのメインオブジェクトです。このオブジェクトは、zip ファイルの処理に使用されるメソッドを実装しています。

手順4:C1ZipFile オブジェクトを初期化するコードを追加します。

Form_Load イベントに次のコードを追加します。

Visual Basic でコードを書く場合

Visual Basic
コードのコピー
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
     ' C1ZipFile メンバを作成します。
    m_Zip = New C1ZipFile()
End Sub

C# でコードを書く場合

C#
コードのコピー
private void Form1_Load(object sender, EventArgs e)
{
  // C1ZipFile メンバを作成します。
    m_Zip = new C1ZipFile();
}

このコードは、新しい C1ZipFile オブジェクトを作成し、それを m_Zip メンバに代入します。この C1ZipFile オブジェクトはまだ使用できないことに注意してください。それには、最初に Open メソッドを使用して既存の zip ファイルにアタッチするか、Create メソッドを使用して新しい zip ファイルにアタッチする必要があります。

手順5:zip ファイルを作成するコードを追加します。

[Zip ファイルの作成]コマンドボタンの Click イベントを処理する次のコードを追加します。

Visual Basic でコードを書く場合

Visual Basic
コードのコピー
Private Sub btnNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNew.Click
     ' ファイルを開くダイアログを表示します。
    Dim fo As SaveFileDialog = New SaveFileDialog()
    fo.FileName = "*.zip"
    If fo.ShowDialog() <> Windows.Forms.DialogResult.OK Then
        Exit Sub
    End If
     ' zip ファイルを開きます。
    Try
        m_Zip.Create(fo.FileName)
    Catch
        MessageBox.Show("Can't create ZIP file, please try again.", "C1Zip")
    End Try
     ' UI を更新します。
    UpdateDisplay()
End Sub

C# でコードを書く場合

C#
コードのコピー
private void btnNew_Click(object sender, EventArgs e)
{
    // ファイルを開くダイアログを表示します。 
    SaveFileDialog fo = new SaveFileDialog();
    fo.FileName = "*.zip";
    if (fo.ShowDialog() != DialogResult.OK ) return;
     // zip ファイルを開きます。 
    try
    {
        m_Zip.Create(fo.FileName);
    }
    catch
    {
        MessageBox.Show("Can't create ZIP file, please try again.", "C1Zip");
    }
     // UI を更新します。 
    UpdateDisplay();
}

手順6:zip ファイルを開くコードを追加します。

[Zip ファイルを開く]コマンドボタンの Click イベントを処理する次のコードを追加します。

Visual Basic でコードを書く場合

Visual Basic
コードのコピー
Private Sub btnOpen_Click(sender As Object, e As EventArgs) Handles btnOpen.Click
     ' ファイルを開くダイアログを表示します。
    Dim fo As OpenFileDialog = New OpenFileDialog()
    fo.FileName = "*.zip"
    If fo.ShowDialog() <> Windows.Forms.DialogResult.OK Then Exit Sub
    Try
        m_Zip.Open(fo.FileName)
    Catch
        MessageBox.Show("Invalid ZIP file, please try again.")
    End Try
      ' UI を更新します。
    UpdateDisplay()
End Sub

C# でコードを書く場合

C#
コードのコピー
private void btnOpen_Click(object sender, EventArgs e)
{
     // ファイルを開くダイアログを表示します。
    OpenFileDialog fo = new OpenFileDialog();
    fo.FileName = "*.zip";
    if (fo.ShowDialog() != DialogResult.OK ) return;
    try
    {
        m_Zip.Open(fo.FileName);
    }
    catch
    {
        MessageBox.Show("Invalid ZIP file, please try again.");
    }
     // UI を更新します。
    UpdateDisplay();
}

重要な行は、C1ZipFile オブジェクトの Open メソッドの呼び出しです。ここで、オブジェクトを既存の zip ファイルにアタッチします。Try/Catch ステートメントは、主に、ユーザーが zip ファイルでないファイルを選択した場合に対処するために使用されます。

ファイルが開いたら、UpdateDisplay ユーティリティ関数を呼び出して、zip ファイルの内容を表示します。

手順7: 表示を更新するコードを追加します。

次に、zip ファイルの内容を表示する UpdateDisplay ユーティリティ関数を追加します。

Visual Basic でコードを書く場合

Visual Basic
コードのコピー
Private Sub UpdateDisplay()
      ' ListView コントロールを更新して、zip ファイルの内容を表示します。
    With ListView1
          ' 既存の項目を削除します。
        .Items.Clear()
         ' 各エントリを追加します。
        Dim ze As C1ZipEntry
        For Each ze In m_Zip.Entries
              ' 圧縮量を計算します。
            Dim pct As Double = 0
            If ze.SizeUncompressed > 0 Then
                pct = 1 - ze.SizeCompressed / ze.SizeUncompressed
            End If
             ' ListView 項目を構築します。
            Dim items(4) As String
            items(0) = ze.FileName
            items(1) = Format(ze.Date, "MM/dd/yy")
            items(2) = Format(ze.SizeUncompressed, "#,##0")
            items(3) = Format(ze.SizeCompressed, "#,##0")
            items(4) = Format(pct, "00 %")
            Dim lvi As ListViewItem = New ListViewItem(items)
              ' ZipEntry を項目タグに保存します。
            lvi.Tag = ze
              ' 項目を ListView に追加します。
            .Items.Add(lvi)
        Next ze
         ' UI を更新します。
        Dim hasEntries As Boolean = (.Items.Count > 0)
        btnExtract.Enabled = hasEntries
        btnRemove.Enabled = hasEntries
        btnTest.Enabled = hasEntries
    End With
End Sub

C# でコードを書く場合

C#
コードのコピー
private void UpdateDisplay()
{
     // 既存の項目を削除します。
    listView1.Items.Clear();
     // 各エントリを追加します。
    foreach (C1ZipEntry ze in m_Zip.Entries)
    {
        // 圧縮量を計算します。
        double pct = 0;
        if (ze.SizeUncompressed > 0)
        {
            pct = 1 - (((double)ze.SizeCompressed) / ((double)ze.SizeUncompressed));
        }
        // ListView 項目を構築します。
        ListViewItem lvi = new ListViewItem(new string[] { ze.FileName, Microsoft.VisualBasic.Strings.Format(ze.Date, "MM/dd/yy"), Microsoft.VisualBasic.Strings.Format(ze.SizeUncompressed, "#,##0"), Microsoft.VisualBasic.Strings.Format(ze.SizeCompressed, "#,##0"), Microsoft.VisualBasic.Strings.Format(pct, "00 %") });
        // ZipEntry を項目タグに保存します。
        lvi.Tag = ze;
        // 項目を ListView に追加します。
        listView1.Items.Add(lvi);
    }
    // UI を更新します。
    bool hasEntries = (listView1.Items.Count > 0);
    btnExtract.Enabled = hasEntries;
    btnRemove.Enabled = hasEntries;
    btnTest.Enabled = hasEntries;
}

重要な行は、最初の C1ZipEntry オブジェクトの宣言と、そのオブジェクトを ForEach ループ内で使用して zip ファイル内のエントリ(m_Zip.Entries)を処理するコードです。

各エントリに対して、C1ZipEntry オブジェクトから抽出された情報を格納する ListViewItem を作成し、新しいエントリを ListView コントロールに追加します。C1ZipEntry オブジェクト自体は ListView 項目の Tag プロパティに保存されます。

最後に、抽出、削除、またはテスト可能なエントリがあるかどうかに応じて、コマンドボタンを有効/無効にします。

手順8:zip ファイルの整合性をテストするコードを追加します。

Zip ファイルのテスト]コマンドボタンの Click イベントを処理する次のコードを追加します。

Visual Basic でコードを書く場合

Visual Basic
コードのコピー
Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click
     ' 各エントリをテストします。
    Dim ze As C1ZipEntry
    For Each ze In m_Zip.Entries
        If Not ze.CheckCRC32() Then
            MessageBox.Show("** Entry " & ze.FileName & " has errors.", "C1Zip", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Exit Sub
        End If
    Next
      ' ここまで到達すれば問題はありません。
    MessageBox.Show("All entries passed CRC check", "C1Zip")
End Sub

C# でコードを書く場合

C#
コードのコピー
private void btnTest_Click(object sender, EventArgs e)
{
      // 各エントリをテストします。
    foreach (C1ZipEntry ze in m_Zip.Entries)
    {
        if (!ze.CheckCRC32())
        {
            MessageBox.Show("** Entry " + ze.FileName + " has errors.", "C1Zip", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }
    } 
     // ここまで到達すれば問題はありません。
    MessageBox.Show("All entries passed CRC check", "C1Zip");
}

重要な行は、C1ZipEntry 変数の宣言と、その変数を使用して zip ファイル内のエントリをループするコードです。次に、各エントリに対して CheckCRC32 メソッドを呼び出して、ファイルに保存されているバイトデータの実際のチェックサムがエントリヘッダに保存されているチェックサムと一致するかどうかを確認します。この関数は、値が一致する場合は true を返します。値が一致しない場合は、false を返して、エントリが破損していることを示します。

手順9:エントリの内容を表示するコードを追加します。

ファイルの表示]コマンドボタンの Click イベントを処理する次のコードを追加します。

Visual Basic でコードを書く場合

Visual Basic
コードのコピー
Private Sub btnView_Click(sender As Object, e As EventArgs) Handles btnView.Click
      ' 最初に選択されたディレクトリではない項目を取得します。
    Dim ze As C1ZipEntry = Nothing
    Dim lvi As ListViewItem
    For Each lvi In ListView1.SelectedItems
        Dim zeItem As C1ZipEntry = lvi.Tag
        If (zeItem.Attributes And FileAttributes.Directory) = 0 Then
            ze = zeItem
            Exit For
        End If
    Next lvi
      ' 項目を取得したことを確認します。
    If ze Is Nothing Then
        MessageBox.Show("Sorry, no files to show...", "C1Zip")
        Exit Sub
    End If
     ' エントリの内容を文字列に読み取ります。
    Dim entry As Stream = ze.OpenReader()
    Dim sr As StreamReader = New StreamReader(entry)
    Dim entryText As String = sr.ReadToEnd()
    entry.Close()
     ' エントリが MessageBox に対して長すぎないようにします。
    If entryText.Length > 16000 Then
        entryText = entryText.Substring(0, 16000)
    End If
      ' メッセージボックスにエントリを表示します。
    MessageBox.Show(entryText, ze.FileName)
End Sub

C# でコードを書く場合

C#
コードのコピー
private void btnView_Click(object sender, EventArgs e)
{
     // 最初に選択されたディレクトリではない項目を取得します。
    C1ZipEntry ze = null;
    foreach (ListViewItem lvi in listView1.SelectedItems)
    {
        C1ZipEntry zeItem = lvi.Tag as C1ZipEntry;
        if ((zeItem.Attributes == 0) && (FileAttributes.Directory == 0))
        {
            ze = zeItem;
            break;
        }
    }
     // 項目を取得したことを確認します。
    if (ze == null )
    {
        MessageBox.Show("Sorry, no files to show...", "C1Zip");
        return;
    }
     // エントリの内容を文字列に読み取ります。
    Stream entry = ze.OpenReader();
    StreamReader sr = new StreamReader(entry);
    string  entryText = sr.ReadToEnd();
    entry.Close();
     // エントリが MessageBox に対して長すぎないようにします。
    if (entryText.Length > 16000 ) 
    {
        entryText = entryText.Substring(0, 16000);
    }
     // メッセージボックスにエントリを表示します。
    MessageBox.Show(entryText, ze.FileName);
}

この関数は、最初に選択されたサブディレクトリではない zip エントリを選択します。有効なエントリが見つからない場合、関数は終了します。

次に、 OpenReader メソッドを呼び出して、エントリの内容の読み取りに使用できるストリームを取得します。この手順には、一時ファイルも余分な遅延もありません。データは、ストリームから読み取られると同時に展開されます。

次に、StreamReader オブジェクトの ReadToEnd メソッドを使用して、エントリの内容を文字列に直接読み取った後、ストリームを閉じます。

最後に、文字列を切り詰めてメッセージボックスに表示します。

この関数は、短いテキストファイルの内容を表示することを目的としています。バイナリファイルの内容を表示しようとすると、数文字しか表示されません。

手順 10:zip ファイルにエントリを追加するコードを追加します。

ファイルの追加]コマンドボタンの Click イベントを処理する次のコードを追加します。

Visual Basic でコードを書く場合

Visual Basic
コードのコピー
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
     ' 追加するファイルのリストを取得します。
    Dim fo As OpenFileDialog = New OpenFileDialog()
    fo.Multiselect = True
    fo.FileName = "*.*"
    If fo.ShowDialog <> Windows.Forms.DialogResult.OK Then Exit Sub
     ' リストにファイルを追加します。
    Dim file As String
    For Each file In fo.FileNames()
        m_Zip.Entries.Add(file)
    Next file
      ' 完了。
    UpdateDisplay()
End Sub

C# でコードを書く場合

C#
コードのコピー
private void btnAdd_Click(object sender, EventArgs e)
{
     // 追加するファイルのリストを取得します。
    OpenFileDialog fo = new OpenFileDialog();
    fo.Multiselect = true;
    fo.FileName = "*.*";
    if (fo.ShowDialog() == DialogResult.OK)
    {
        // リストにファイルを追加します。
        foreach (string file in fo.FileNames)
        {
            m_Zip.Entries.Add(file);
        }
          // 完了。
        UpdateDisplay();
    }
}

zip ファイルに新しいエントリを追加することは簡単です。重要な行は、C1ZipFile オブジェクトの Add メソッドの呼び出しだけです。ここで、追加するファイルの完全名を文字列で渡します。これで、やることはすべてです。

手順 11:zip エントリを抽出するコードを追加します。

ファイルの抽出]コマンドボタンの Click イベントを処理する次のコードを追加します。

Visual Basic でコードを書く場合

Visual Basic
コードのコピー
Private Sub btnExtract_Click(sender As Object, e As EventArgs) Handles btnExtract.Click
      ' いくつかのエントリを選択していることを確認します。
    Dim cnt As Integer = ListView1.SelectedIndices.Count
    If cnt = 0 Then
        MessageBox.Show("Sorry, no files to extract...", "C1Zip")
        Exit Sub
    End If
     ' ユーザーに確認します。
    Dim dr As DialogResult
    Dim msg As String
    msg = "Please confirm that you want to extract " + cnt.ToString() + " entries."
    dr = MessageBox.Show(msg, "C1Zip", MessageBoxButtons.OKCancel, MessageBoxIcon.Question)
    If dr <> Windows.Forms.DialogResult.OK Then Exit Sub
     ' 選択されたすべてのエントリを抽出します。
    Dim lvi As ListViewItem
    Dim ze As C1ZipEntry
    For Each lvi In ListView1.SelectedItems
        ze = lvi.Tag
        If ze.SizeCompressed > 0 Then
             m_Zip.Entries.Extract(ze.FileName)
        End If
    Next lvi
      ' 完了。
    UpdateDisplay()
End Sub

C# でコードを書く場合

C#
コードのコピー
private void btnExtract_Click(object sender, EventArgs e)
{
     // いくつかのエントリを選択していることを確認します。
    int cnt = listView1.SelectedIndices.Count;
    if (cnt == 0)
    {
        MessageBox.Show("Sorry, no files to extract...", "C1Zip");
        return;
    }
     // ユーザーに確認します。
    DialogResult dr;
    string  msg;
    msg = "Please confirm that you want to extract " + cnt.ToString() + " entries.";
    dr = MessageBox.Show(msg, "C1Zip", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
    if ( dr != DialogResult.OK )  return;
     // 選択されたすべてのエントリを抽出します。
    C1ZipEntry ze;
    foreach (ListViewItem lvi in ListView1.SelectedItems)
    {
        ze = (C1ZipEntry)lvi.Tag;
        if ( ze.SizeCompressed > 0 )
        {
            m_Zip.Entries.Extract(ze.FileName);
        }
    }
      // 完了。
    UpdateDisplay();
}

最も重要な行は、C1ZipFile オブジェクトの Entries プロパティの  Extract メソッドの呼び出しです。 パラメータは、エントリのファイル名を含む文字列です。これは、エントリの FileName プロパティに保存されています。).

デフォルトでは、Extract メソッドはエントリを展開し、それを zip ファイルのディレクトリに保存します。このメソッドには別のバージョンもあります。そこでは、出力ディレクトリと展開ファイルのファイル名を指定できます。詳細については、「C1.C1Zip 名前空間 」セクションを参照してください。

手順 12:zip ファイルからエントリを削除するコードを追加します。

ファイルの削除]コマンドボタンの Click イベントを処理する次のコードを追加します。

Visual Basic でコードを書く場合

Visual Basic
コードのコピー
Private Sub btnRemove_Click(sender As Object, e As EventArgs) Handles btnRemove.Click
      ' いくつかのエントリを選択していることを確認します。
    Dim cnt As Integer = ListView1.SelectedIndices.Count
    If cnt = 0 Then
        MessageBox.Show("Oops, no files to remove...", "C1Zip")
        Exit Sub
    End If
     ' ユーザーに確認します。
    Dim dr As DialogResult
    Dim msg As String
    msg = "Please confirm that you want to delete " + cnt.ToString() + " entries."
    dr = MessageBox.Show(msg, "C1Zip", MessageBoxButtons.OKCancel, MessageBoxIcon.Question)
    If dr <> Windows.Forms.DialogResult.OK Then Exit Sub
      ' 選択されたすべてのエントリを削除します。
    Dim lvi As ListViewItem
    Dim ze As C1ZipEntry
    For Each lvi In ListView1.SelectedItems
        ze = lvi.Tag
        m_Zip.Entries.Remove(ze.FileName)
    Next lvi
      ' 完了。
    UpdateDisplay()
End Sub

C# でコードを書く場合

C#
コードのコピー
private void btnRemove_Click(object sender, EventArgs e)  {
     // いくつかのエントリを選択していることを確認します。
    int cnt = listView1.SelectedIndices.Count;
    if (cnt == 0 )
    {
        MessageBox.Show("Oops, no files to remove...", "C1Zip");
        return;
    }
     // ユーザーに確認します。
     DialogResult dr;
    string  msg;
    msg = "Please confirm that you want to delete " + cnt.ToString() + " entries.";
    dr = MessageBox.Show(msg, "C1Zip", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
    if (dr != DialogResult.OK) return;
     // 選択されたすべてのエントリを削除します。
    foreach (ListViewItem lvi in listView1.SelectedItems)
    {
        C1ZipEntry ze = (C1ZipEntry)lvi.Tag;
        if (ze.SizeCompressed > 0)
        {
            m_Zip.Entries.Remove(ze.FileName);
        }
    } 
      // 完了。
    UpdateDisplay();
}

最も重要な行は、C1ZipFile オブジェクトの Entries プロパティの Remove メソッドの呼び出しです。パラメータは、エントリのファイル名を含む文字列です。これは、エントリの FileName プロパティに保存されています。

これで「Zip ファイルの処理」チュートリアルは終了です。