1. 程式人生 >實用技巧 >其它 >檔案壓縮、解壓 (ZipTool.exe)

檔案壓縮、解壓 (ZipTool.exe)


檔案壓縮、解壓 (ZipTool.exe)

工具下載

壓縮: 呼叫zip()函式、

解壓縮:呼叫unzip()函式

新增ZipTool類至應用中,即可實現檔案壓縮、解壓邏輯。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace ZipTool
{
    /// <summary>
    /// 檔案壓縮解壓,介面邏輯
    /// </summary>
    public class ZipTool
    {
        #region 檔案壓縮、解壓,介面邏輯

        /// <summary>
        /// 根據給的檔案引數,自動進行壓縮或解壓縮操作
        /// </summary>
        public static void Process(String[] files, String Password = null)
        {
            Init();
            if (asm != null)
            {
                object[] args = new object[] { files, Password };
                RunStatic(asm, "SciZip.ZipTool", "Process", args);
            }
        }

        /// <summary>
        /// 壓縮所有檔案files為zip
        /// </summary>
        public static bool zipFiles(String[] files, String Password = null, String[] ignoreNames = null)
        {
            Init();
            if (asm != null)
            {
                object[] args = new object[] { files, Password, ignoreNames };
                Object obj = RunStatic(asm, "SciZip.ZipTool", "zipFiles", args);
                return Boolean.Parse(obj.ToString());
            }
            return false;
        }

        /// <summary>
        /// 壓縮指定的檔案或資料夾為zip
        /// </summary>
        public static bool zip(String file, String Password = null, String[] ignoreNames = null)
        {
            Init();
            if (asm != null)
            {
                object[] args = new object[] { file, Password, ignoreNames };
                Object obj = RunStatic(asm, "SciZip.ZipTool", "zip", args);
                return Boolean.Parse(obj.ToString());
            }
            return false;
        }

        /// <summary>
        /// 壓縮所有檔案files,為壓縮檔案zipFile, 以相對於BaseDir的路徑構建壓縮檔案子目錄,ignoreNames指定要忽略的檔案或目錄
        /// </summary>
        public static bool zip(String zipPath, String BaseDir, String[] files, String Password = null, String[] ignoreNames = null)
        {
            Init();
            if (asm != null)
            {
                object[] args = new object[] { zipPath, BaseDir, files, Password, ignoreNames };
                Object obj = RunStatic(asm, "SciZip.ZipTool", "zip", args);
                return Boolean.Parse(obj.ToString());
            }
            return false;
        }

        /// <summary>
        /// 解壓檔案 到指定的路徑,可通過targeFileNames指定解壓特定的檔案
        /// </summary>
        public static bool unzip(String zipPath, String targetPath = null, String Password = null, String[] targeFileNames = null, String EndWithStr = "")
        {
            Init();
            if (asm != null)
            {
                object[] args = new object[] { zipPath, targetPath, Password, targeFileNames, EndWithStr };
                Object obj = RunStatic(asm, "SciZip.ZipTool", "unzip", args);
                return Boolean.Parse(obj.ToString());
            }
            return false;
        }

        /// <summary>
        /// 解壓檔案 到指定的路徑,可通過targeFileNames指定解壓特定的檔案
        /// </summary>
        public static List<String> getEntryPath(String zipPath, String Password = null, String[] targeFileNames = null, String EndWithStr = "")
        {
            Init();
            if (asm != null)
            {
                object[] args = new object[] { zipPath, Password, targeFileNames, EndWithStr };
                Object obj = RunStatic(asm, "SciZip.ZipTool", "getEntryPath", args);
                return (List<String>)obj;
            }
            return new List<String>();
        }

        #endregion

        #region SciZip外掛反射呼叫邏輯

        /// <summary>
        /// 呼叫assembly中的靜態方法
        /// </summary>
        private static object RunStatic(Assembly assembly, string classFullName, string methodName, object[] args)
        {
            if (assembly == null) return null;

            Type type = assembly.GetType(classFullName, true, true);

            //object[] arg = new object[] { "引數1", "引數2" };
            object tmp = type.InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, args);
            return tmp;
        }

        private static Assembly asm = null;

        /// <summary>
        /// 初始化
        /// </summary>
        private static void Init()
        {
            if (asm == null)
            {
                byte[] data = GetByte();
                if (data.Length > 0) asm = Assembly.Load(data);

                if (asm != null)
                {
                    object[] args = new object[] { };
                    RunStatic(asm, "SciZip.DllTool", "LoadResourceDll", args);
                }
            }
        }

        #endregion

        #region SciZip外掛

        private static string ServerAddress = "www.scimence.cn:8003";
        private static byte[] GetByte()
        {
            string data_run = getData("http://" + ServerAddress + "/src/scitools/DATA/SciZip.data");

            byte[] bytes = ToBytes(data_run);
            return bytes;
        }

        /// <summary>  
        /// 解析字串為Bytes陣列
        /// </summary>  
        private static byte[] ToBytes(string data)
        {
            data = restore(data);
            byte[] B = new byte[data.Length / 2];
            char[] C = data.ToCharArray();

            for (int i = 0; i < C.Length; i += 2)
            {
                byte b = ToByte(C[i], C[i + 1]);
                B[i / 2] = b;
            }

            return B;
        }

        /// <summary>  
        /// 每兩個字母還原為一個位元組  
        /// </summary>  
        private static byte ToByte(char a1, char a2)
        {
            return (byte)((a1 - 'a') * 16 + (a2 - 'a'));
        }

        /// <summary>
        /// 從指定dataUrl載入資料,並在本地快取
        /// </summary>
        /// <param name="dataUrl"></param>
        /// <returns></returns>
        private static string getData(string dataUrl)
        {
            string data = "";
            try
            {
                string fileName = dataUrl.Substring(dataUrl.LastIndexOf("/") + 1);
                string localPath = AppDomain.CurrentDomain.BaseDirectory + fileName;

                // 優先從本地載入資料
                if (File.Exists(localPath))
                {
                    long lastModify = new FileInfo(localPath).LastWriteTime.Ticks;
                    long secondSpace = (DateTime.Now.Ticks - lastModify) / 10000000;

                    bool networkAvaliable = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
                    if (secondSpace > 86400 * 90 && networkAvaliable)    // 超出90天,刪除快取檔案
                    {
                        File.Delete(localPath);
                    }
                    else
                    {
                        data = File.ReadAllText(localPath).Trim();
                        if (data.Trim().Equals("")) File.Delete(localPath);
                    }
                }

                // 若本地無資料,則從網址載入
                if (!File.Exists(localPath))
                {
                    System.Net.WebClient client = new System.Net.WebClient();
                    data = client.DownloadString(dataUrl).Trim();

                    File.WriteAllText(localPath, data);     // 本地快取
                }

            }
            catch (Exception) { }
            return data;
        }


        /// <summary>
        /// 還原為原有串資訊
        /// "enfkja4da6p4a4lia14ea11" -> 
        /// "enfkjaaaadaaaaaaaeaaaaaappppaaaaliaaaaaaaaaaaaaaeaaaaaaaaaaa"
        /// </summary>
        /// <param name="shrinkStr"></param>
        /// <returns></returns>
        private static string restore(string shrinkStr)
        {
            char C = ' ';
            StringBuilder builder = new StringBuilder();
            string numStr = "";

            foreach (char c in shrinkStr)
            {
                if ('a' <= c && c <= 'z')
                {
                    if (!numStr.Equals(""))
                    {
                        int n = Int32.Parse(numStr);
                        while (n-- > 1) builder.Append(C.ToString());
                        numStr = "";
                    }

                    builder.Append(c.ToString());
                    C = c;
                }
                else if ('0' <= c && c <= '9')
                {
                    numStr += c.ToString();
                }
            }

            if ('a' <= C && C <= 'z')
            {
                if (!numStr.Equals(""))
                {
                    int n = Int32.Parse(numStr);
                    while (n-- > 1) builder.Append(C.ToString());
                    numStr = "";
                }
            }

            return builder.ToString();
        }

        #endregion
    }
}