Unity C# Zip化したアセットバンドル(ファイル)を解凍

●dotnetzipのページ　ここからダウンロードする
 http://dotnetzip.codeplex.com/

●上記ダウンロードの中にある**Ionic.Zip.dll**をUnityが認識するScriptsなどの適当なフォルダへおく

●下記ソースコードを呼ぶようにする。
　(今回はEditorからコールするようにしたけど本来は内部から呼ぶはず)

```csharp:UnzipBundleFIle.cs
using UnityEngine;
using UnityEditor;
using System.Collections;
using Ionic.Zip;
using Ionic.Zlib;

public class UnzipBundleFIle
{
    [MenuItem("Assets/UnzipBundleFiles")]
    static void UnZipBundleFile()
    {
        // zipファイル読み込み
        using (ZipFile zip = new ZipFile("・・・・・・/myAssetBundle2.zip"))
        {
            // 出力先フォルダ名、たぶんUnity側が読めるフォルダじゃなきゃいけない
            string exportPath = "・・・・・/Assets";
            //ZIP書庫内のエントリを取得 
            foreach (Ionic.Zip.ZipEntry entry in zip)
            {
                //エントリを展開する 
                entry.Extract(exportPath);
            }
        }

        Debug.Log("UnZip OK");
    }
}
```

# ●上記実機で問題が出たので追記

　------------------ **問題点と解決方法** ------------------
　●iOSでクロスコンパイルエラーが出る。
　　**解決方法**：**Ionic.Zip.dll**では無く**Ionic.Zip.CF.dll**を使用する。

　　**Ionic.Zip.CF.dll**は**http://dotnetzip.codeplex.com/**からダウンロードしたフォルダ構成の
　　**zip-v1.9-CompactFramework**の**Release**にある。

　●Androidでビルドすると下記①で落ちて②のエラーが出る
　　①using (ZipInputStream decompressStream = new ZipInputStream("zipファイルのMemoryStream"))
　　②Encoding name 'IBM437' not supported. Parameter name:name

　　**解決方法**：**C:\Program Files\Unity501f1\Editor\Data\Mono\lib\mono\2.0**にある
　　　　　　　　**I18N.West.dll**を使用する。

　　　実行するUnityプロジェクトのAssetsフォルダの下に上記DLLを入れてビルドするとエラーにはならない。

　　**参考ページ**：
　　　http://forum.unity3d.com/threads/ionic-zip-dll-does-not-work-in-build.165841/
　　　
　　　http://stackoverflow.com/questions/10858690/get-encoding-fails-when-i-build-monodroid-project-with-unshared-runtime
　　　これを見る限りMonoのAndroidビルドに**IBM437**のエンコードが含まれていないみたい。

 

**ソースも忘れないようにメモ**

```csharp:UnZipThread

using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Text.RegularExpressions;
using Ionic.Zip;

public class UnZipThread{

    public Action UnZipProgress;
    public Action UnZipEnd;
    public Action NextCallFunction;

    public AutoResetEvent ThreadEvent
    {
        get { return _threadEvent; }
    }


    private AutoResetEvent _threadEvent;
    public bool ThreadSleepFlg = true;


    //// 処理中INDEX
    //private int _listIndex;
    //public int ListIndex
    //{
    //    get { return _listIndex; }
    //    set { this._listIndex = value; }
    //}

    // 書込先ストリーム
    private MemoryStream _unZipMs = new MemoryStream();
    public MemoryStream UnZipMs
    {
        get { return _unZipMs; }
        set { this._unZipMs = value; }
    }


    // 保存先ファイルパス
    private string _savePath;
    public string SavePath
    {
        get { return _savePath; }
        set { this._savePath = value; }
    }


    // エラー文字列
    private string _errString = "";
    public string ErrString
    {
        get { return _errString; }
        set { this._errString = value; }
    }


    // 書込済み文字数
    private long _fileLength = 0;
    public long FileLength
    {
        get { return _fileLength; }
        set { this._fileLength = value; }
    }

    // チェック用ファイル名
    private string _fileName;
    public string FileName
    {
        get { return _fileName; }
        set { this._fileName = value; }
    }

    // UnZip進捗
    private float _unZipProgressValue;
    public float UnZipProgressValue
    {
        get { return _unZipProgressValue; }
        set { this._unZipProgressValue = value; }
    }


    private Thread ThreadEntity;


    /// <summary>
    /// Zip解凍スレッドスタート
    /// </summary>
    /// <returns></returns>
    public void ThreadDownLoadStart()
    {
        _errString = "ZipThreadStart";
        ThreadSleepFlg = false;
        Thread unzip = new Thread(new ThreadStart(FileUnZip));
        _threadEvent = new AutoResetEvent(true);
        unzip.Start();
    }

    /// <summary>
    /// Zip解凍用スレッド休止
    /// </summary>
    public void ThreadDownLoadPause()
    {
        _threadEvent.WaitOne();
        ThreadSleepFlg = true;
    }

    /// <summary>
    /// Zip解凍用スレッド再開
    /// </summary>
    public void ThreadDownLoadReStart()
    {
        _threadEvent.Set();
        ThreadSleepFlg = false;
    }

    /// <summary>
    /// Zip解凍用スレッドリセット
    /// </summary>
    public void ThreadDownLoadReset()
    {
        ThreadSleepFlg = true;
        _threadEvent.Reset();
        _threadEvent = null;

    }


    /// <summary>
    /// Unzipストリームセット処理
    /// </summary>
    /// <param name="addUrl"></param>
    private void UnZipDataStreamSet(MemoryStream unzipdata,DownLoadData setdownloaddata)
    {
        setdownloaddata.ZipFileData = new MemoryStream();
        lock (setdownloaddata.ZipFileData)
        {
            MemoryStream UnZipStream = new MemoryStream();
            UnZipStream = unzipdata;
            setdownloaddata.UnZipDataList.Add(UnZipStream);
        }
    }

    /// <summary>
    /// ファイルの解凍処理
    /// </summary>
    public void FileUnZip()
    {
        while (true)
        {
            int downloadcount = SingletonDownLoadData.Instance.DownLoadDataList.Where(download => download.UnZipEndFlg == false).Count();
            if (downloadcount > 0)
            {
                //_errString = "DownLoadCnt=" + downloadcount.ToString();
                // 最初にヒットしたものを取得
                DownLoadData setDownLoadData = SingletonDownLoadData.Instance.DownLoadDataList.Where(download => download.UnZipEndFlg == false).First();

                try
                {
                    _errString = "ZipCountOK";
                    // Zipファイルストリームの読み取り位置をゼロにセット
                    setDownLoadData.ZipFileData.Position = 0; ;
                    _errString = "ZipPos 0";

                    using (ZipInputStream decompressStream = new ZipInputStream(setDownLoadData.ZipFileData))
                    {
                        _errString = "ZipInputStream";
                        ZipEntry zipEntry = decompressStream.GetNextEntry();
                        while (zipEntry != null)
                        {
                            _errString = _errString + " ZipEntry";
                            // 書き込み領域を初期化
                            MemoryStream writeSpace = new MemoryStream();
                            writeSpace.Position = 0;
                            _errString = _errString + " UnZip Position = 0";
                            //展開するファイルを読み込む
                            byte[] buffer = new byte[2048];
                            int len;
                            while ((len = decompressStream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                //ファイルに書き込む
                                writeSpace.Write(buffer, 0, len);
                            }
                            _errString = _errString + " UnZip writeSpace";

                            // 書き込まれたストリームをデータクラスのファイル用のリストに追加
                            UnZipDataStreamSet(writeSpace, setDownLoadData);
                            setDownLoadData.FileNameList.Add(zipEntry.FileName);

                            _fileName = zipEntry.FileName;
                            UnZipProgress();
                            ////******************************************************************************


                            ////展開先のファイル名を決定
                            //string fileName = System.IO.Path.GetFileName(zipEntry.FileName);
                            ////展開先のフォルダを決定
                            //string destDir = System.IO.Path.Combine(@"C:\temp",
                            //    System.IO.Path.GetDirectoryName(zipEntry.FileName));
                            //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);
                            ////ファイルに書き込む
                            //writer.Write(writeSpace.GetBuffer(), 0, (int)writeSpace.Length);
                            ////閉じる
                            //writer.Close();

                            ////******************************************************************************

                            // Zipファイル内のエントリーを次に進める
                            zipEntry = decompressStream.GetNextEntry();
                        }
                        setDownLoadData.UnZipEndFlg = true;
                    }
                    _errString = _errString + " UnZip OK";
                }
                catch (Exception ex)
                {
                    _errString = _errString + " Error=" + ex.Message;
                    // スレッドをスリープ状態へ
                    ThreadDownLoadPause();
                }
            }
            else
            {
                _errString = " ThreadSuspend";
                UnZipEnd();
                // 処理するものがなければスレッド一時停止
                // スレッドをスリープ状態へ
                ThreadDownLoadPause();
            }
        }
    }
}

```