C#實戰小技巧(十四):文件/文件夾的壓縮與解壓實例

在C#中藉助ICSharpCode.SharpZipLib,可實現文件/文件夾的壓縮和解壓,GitHub下載地址:https://github.com/icsharpcode/SharpZipLib
1.簡單壓縮

		/// <summary>
        /// 生成Zip壓縮文件
        /// </summary>
        /// <param name="zipPath">生成壓縮包名稱</param>
        /// <param name="filePath">被壓縮文件列表</param>
        public void CreateZipFile(string zipPath, List<string> filePath)
        {
            using (ZipOutputStream zip = new ZipOutputStream(File.Open(zipPath, FileMode.OpenOrCreate)))
            {
                //循環設置目錄下所有文件(支持子目錄搜索)
                foreach (string file in filePath)
                {
                    if (File.Exists(file))
                    {
                        FileInfo item = new FileInfo(file);
                        FileStream fs = File.OpenRead(item.FullName);
                        byte[] buffer = new byte[fs.Length];
                        fs.Read(buffer, 0, buffer.Length);

                        ZipEntry entry = new ZipEntry(item.Name);
                        zip.PutNextEntry(entry);
                        zip.Write(buffer, 0, buffer.Length);
                    }
                }
            }
        }

2.多級目錄的文件夾壓縮

		/// <summary>
	    /// 壓縮進度委託
	    /// </summary>
	    /// <param name="msgid">ID</param>
	    /// <param name="progress">進度</param>
	    public delegate void ZipProgressDel(string msgid, double progress);
    
        /// <summary>
        /// 壓縮進度事件
        /// </summary>
        public event ZipProgressDel OnZipProgressEvent;

		/// <summary>
        /// Zip壓縮多層目錄
        /// </summary>
        /// <param name="msgId">ID</param>
        /// <param name="zipedFile">生成的壓縮文件名稱</param>
        /// <param name="strDirectory">被壓縮的目錄</param>
        public void ZipFileDirectory(string msgId, string zipedFile, string strDirectory)
        {
            using (System.IO.FileStream ZipFile = System.IO.File.Create(zipedFile))
            {
                using (ZipOutputStream s = new ZipOutputStream(ZipFile))
                {
                    ZipStep(msgId, strDirectory, s, string.Empty, true);
                }
            }
        }

        /// <summary>
        /// 遞歸遍歷目錄
        /// </summary>
        /// <param name="msgId">ID</param>
        /// <param name="strDirectory">被壓縮的目錄</param>
        /// <param name="s">生成的壓縮文件輸出流</param>
        /// <param name="parentPath">父路徑</param>
        /// <param name="showProgress">是否顯示進度</param>
        private void ZipStep(string msgId, string strDirectory, ZipOutputStream s, string parentPath, bool showProgress)
        {
            if (strDirectory[strDirectory.Length - 1] != Path.DirectorySeparatorChar)
            {
                strDirectory += Path.DirectorySeparatorChar;
            }

            Crc32 crc = new Crc32();
            string[] filenames = Directory.GetFileSystemEntries(strDirectory);
            int finished = 0;
            int total = filenames.Count();
            foreach (string file in filenames)// 遍歷所有的文件和目錄
            {
                if (!this.fileOnlineDic.ContainsKey(msgId))
                {
                    // 發現取消發送後,停止壓縮文件
                    return;
                }

                if (Directory.Exists(file))// 先當作目錄處理如果存在這個目錄就遞歸Copy該目錄下面的文件
                {
                    string pPath = parentPath;
                    pPath += file.Substring(file.LastIndexOf("\\") + 1);
                    pPath += "\\";
                    ZipStep(msgId, file, s, pPath, false);
                }
                else // 否則直接壓縮文件
                {
                    //打開壓縮文件
                    using (FileStream fs = File.OpenRead(file))
                    {

                        byte[] buffer = new byte[fs.Length];
                        fs.Read(buffer, 0, buffer.Length);

                        string fileName = parentPath + file.Substring(file.LastIndexOf("\\") + 1);
                        ZipEntry entry = new ZipEntry(fileName);

                        entry.DateTime = DateTime.Now;
                        entry.Size = fs.Length;

                        fs.Close();

                        crc.Reset();
                        crc.Update(buffer);

                        entry.Crc = crc.Value;
                        s.PutNextEntry(entry);

                        s.Write(buffer, 0, buffer.Length);
                    }
                }

                finished++;
                if (showProgress && this.OnZipProgressEvent != null)
                {
                    double progress = Convert.ToDouble(100 * finished / total);
                    this.OnZipProgressEvent(msgId, progress);
                }
            }
        }

3.解壓


        /// <summary>
        /// 解壓Zip文件
        /// </summary>
        /// <param name="zipPath">zip文件路徑</param>
        /// <param name="targetPath">解壓目標路徑</param>
        public void UnZip(string zipPath, string targetPath)
        {
            if (!File.Exists(zipPath))
            {
                LOG.Error("壓縮文件不存在,無法解壓");

                return;
            }

            if (!Directory.Exists(targetPath))
            {
                Directory.CreateDirectory(targetPath);
            }

            //目錄結尾
            if (!targetPath.EndsWith("\\"))
            {
                targetPath = new StringBuilder(targetPath).Append("\\").ToString();
            }

            using (ZipInputStream zip = new ZipInputStream(File.OpenRead(zipPath)))
            {
                ZipEntry theEntry = null;
                while ((theEntry=zip.GetNextEntry()) != null)
                {
                    string directoryName = string.Empty;
                    string pathToZip = string.Empty;
                    pathToZip = theEntry.Name;

                    if (!string.IsNullOrEmpty(pathToZip))
                    {
                        directoryName = new StringBuilder(Path.GetDirectoryName(pathToZip)).ToString();
                        if (!directoryName.EndsWith("\\"))
                        {
                            directoryName = new StringBuilder(directoryName).Append("\\").ToString();
                        }
                    }

                    string fileName = Path.GetFileName(pathToZip);
                    Directory.CreateDirectory(new StringBuilder(targetPath).Append(directoryName).ToString());
                    if (!string.IsNullOrEmpty(fileName))
                    {
                        string filePath = new StringBuilder(targetPath).Append(directoryName).Append(fileName).ToString();
                        using (FileStream streamWriter = File.Create(filePath))
                        {
                            int size = 2048;
                            byte[] data = new byte[2048];
                            while (true)
                            {
                                size = zip.Read(data, 0, data.Length);

                                if (size > 0)
                                    streamWriter.Write(data, 0, size);
                                else
                                    break;
                            }

                            streamWriter.Close();
                        }
                    }
                }

                zip.Close();
            }
        }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章