NonSoft

フォルダをZIPファイル圧縮/解凍する
サンプル(C#.NET)


 サンプル(ソース/コード)
<このサンプルの概要>
J#.NET(vjslib.dll)を使用してフォルダをまるごと ZIPファイル圧縮/解凍するサンプルです。
フォルダを1つのファイルとしてバックアップする時に有効な方法だと思います。
色々調べましたがこれが一番良い方法では!??
参照設定にvjslibを追加してお試しください。このサンプルの動作環境として.NET Framework2.0と
J#.NET2.0 で動作確認しています。VS.NET2005には.NET Framework2.0とJ#.NET2.0が含まれていますが、
.NET Framework2.0ランタイムには J#.NET2.0ランタイムが含まれていませんので別途ダウンロード
する必要があります。

VB.NET版は フォルダをZIPファイル圧縮/解凍するサンプル(VB.NET) です。

このサンプルは空のフォルダもZIPに含めるようにしていますが、Compressed (zipped) Foldersで
見るとフォルダがファイルのように表示されたりします。しかし、解凍(というか展開)してみると
問題なく展開されます。空のフォルダも作成されます。疑問&調査中!!現在愛用しているフリーの
解凍ツールでは何の問題も無いのですが。

<このサンプルの見直しが必要な箇所>
(1)ファイルのクローズ処理はtry catch finallyで確実にクローズしましょう!!
(2)進捗状況が分かるようにした方が良いでしょう!!

★フォルダをZIPファイル圧縮/解凍するクラス(JZip.cs)
//****************************************************************************
// 機能名    : JZip.cs
// 機能説明  : ZIP圧縮/解凍クラス
// 備考      :
// 著作権    : Copyright(C) 2010 のん All rights reserved
// ---------------------------------------------------------------------------
// 使用条件  : このサイトの内容を使用(流用/改変/転載/等全て)した成果物を不特定
//           : 多数に公開/配布する場合は、このサイトを参考にした旨を記述してく
//           : ださい。(例)WEBページやReadMeにリンクを貼ってください
// ---------------------------------------------------------------------------
//****************************************************************************
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace JZip
{
    class JZip
    {
        /// <summary>
        /// 圧縮
        /// </summary>
        /// <param name="zipFile">ZIPファイル</param>
        /// <param name="srcPath">圧縮するFile/Folder</param>
        public static void Compress(String zipFile, String srcPath)
        {
            // 圧縮するファイルの一覧作成
            Boolean isFolder = false;
            String[] filePaths = new String[1] { "" };
            if (System.IO.Directory.Exists(srcPath))
            {
                // フォルダの時
                String fileLists = getFolderFileList(srcPath);
                if ("".Equals(fileLists) == false)
                {
                    filePaths = fileLists.Split('\n');
                    isFolder = true;
                }
            }
            else
            {
                // ファイルの時
                filePaths[0] = srcPath;
            }

            // ZIPファイルオープン
            java.io.FileOutputStream fos = new java.io.FileOutputStream(zipFile);
            java.util.zip.ZipOutputStream zos = new java.util.zip.ZipOutputStream(fos);

            // ZIPにファイルを追加する
            foreach (String fpt in filePaths)
            {
                if ("".Equals(fpt)) continue;

                // ZIPに追加するときのファイル名を決定する
                String f;
                if (isFolder == false)
                {
                    // ディレクトリ無
                    f = System.IO.Path.GetFileName(fpt);
                }
                else
                {
                    // ディレクトリ有
                    f = fpt.Remove(0, srcPath.Length);
                }
                if ("\\".Equals(f.Substring(0, 1))) f = f.Substring(1);
                f = f.Replace("\\", "/");

                // エントリ作成
                java.util.zip.ZipEntry ze = new java.util.zip.ZipEntry(f);

                // 圧縮メソッドを設定
                ze.setMethod(java.util.zip.ZipEntry.DEFLATED);

                // 更新日時設定
                ze.setTime(toEpochTime(System.IO.File.GetLastWriteTime(fpt)));

                // エントリ追加
                zos.putNextEntry(ze);

                // 圧縮データ書込
                if ("\\".Equals(fpt.Substring(fpt.Length - 1)) == false)
                {
                    int len;
                    sbyte[] buffer = new sbyte[8192];
                    // ファイルオープン
                    java.io.FileInputStream fis = new java.io.FileInputStream(fpt);
                    // ファイル読込み
                    while ((len = fis.read(buffer, 0, buffer.Length)) > 0)
                    {
                        // ファイル書込み
                        zos.write(buffer, 0, len);
                    }
                    // 閉じる
                    fis.close();
                }

                // 閉じる
                zos.closeEntry();
                Application.DoEvents();
            }

            // ZIPファイルクローズ
            zos.close();
            fos.close();
        }

        /// <summary>
        /// 解凍
        /// </summary>
        /// <param name="zipFile">ZIPファイル</param>
        /// <param name="dstPath">解凍するFolder</param>
        public static void Extract(String zipFile, String dstPath)
        {
            // フォルダ作成
            if (System.IO.Directory.Exists(dstPath) == false)
            {
                System.IO.Directory.CreateDirectory(dstPath);
            }

            // ZIPファイルオープン
            java.io.FileInputStream fis = new java.io.FileInputStream(zipFile);
            java.util.zip.ZipInputStream zis = new java.util.zip.ZipInputStream(fis);
            //zis.Password = "pass";

            // ZIP内のファイル情報を取得
            java.util.zip.ZipEntry ze;
            while ((ze = zis.getNextEntry()) != null)
            {
                // ファイル名取得
                String fileName = ze.getName();

                // 解凍先のパス設定
                String fullPath = System.IO.Path.Combine(dstPath, fileName);
                fullPath = fullPath.Replace("/", "\\");

                if (ze.isDirectory() == false)
                {
                    int len;
                    sbyte[] buffer = new sbyte[8192];

                    // ファイルオープン
                    java.io.FileOutputStream fos = new java.io.FileOutputStream(fullPath);

                    // ファイル読込み
                    while ((len = zis.read(buffer, 0, buffer.Length)) > 0)
                    {
                        fos.write(buffer, 0, len);
                    }

                    // 閉じる
                    fos.close();
                    // ファイルの更新日時設定
                    System.IO.File.SetLastWriteTime(fullPath, fromEpochTime(ze.getTime()));
                }
                else
                {
                    // フォルダ作成
                    System.IO.Directory.CreateDirectory(fullPath);
                }
                Application.DoEvents();
            }

            // ZIPファイルクローズ
            zis.close();
            fis.close();
        }

        /// <summary>
        /// フォルダとファイルの一覧を取得
        /// </summary>
        /// <param name="srcPath">一覧取得するFolder</param>
        /// <returns>フォルダとファイルの一覧(改行区切り)</returns>
        private static String getFolderFileList(String srcPath)
        {
            String flist = "";
            DirectoryInfo current = new DirectoryInfo(srcPath);

            // ファイルの一覧作成
            foreach (FileInfo file in current.GetFiles())
            {
                if ("".Equals(flist) == false) flist += "\n";
                flist += file.FullName;
            }

            // フォルダの一覧作成
            foreach (DirectoryInfo dir in current.GetDirectories())
            {
                if ("".Equals(flist) == false) flist += "\n";
                flist += dir.FullName + "\\";
                string str = getFolderFileList(dir.FullName);
                if ("".Equals(str) == false)
                {
                    if ("".Equals(flist) == false) flist += "\n";
                    flist += str;
                }
            }

            Application.DoEvents();
            return flist;
        }

        /// <summary>
        /// DateTimeをエポック値に変換する
        /// </summary>
        /// <param name="dt">DateTime</param>
        /// <returns>エポック値</returns>
        public static long toEpochTime(DateTime dt)
        {
            double epo = (dt.ToUniversalTime().Ticks - 621355968000000000) / 10000.0; ;
            return (long)(epo);
        }

        /// <summary>
        /// エポック値をDateTimeに変換する
        /// </summary>
        /// <param name="dt">エポック値</param>
        /// <returns>DateTime</returns>
        public static DateTime fromEpochTime(long epo)
        {
            DateTime dt = new DateTime(epo * 10000 + 621355968000000000);
            return dt.ToLocalTime();
        }
    }
}

★テスト用フォーム(Form1.cs)
public partial class Form1 : Form
{
    private void Button1_Click(object sender, EventArgs e)
    {
        // フォルダ圧縮
        JZip.Compress(@"d:\temp\test.zip", @"d:\temp\test1");
        // 解凍
        JZip.Extract(@"d:\temp\test.zip", @"d:\temp\test2");
        // ファイル圧縮
        JZip.Compress(@"d:\temp\test.zip", @"d:\temp\test3.txt");
        // 解凍
        JZip.Extract(@"d:\temp\test.zip", @"d:\temp\test4");
    }
}