C# ZipHelper C#公共類 -- ICSharpCode.SharpZipLib.dll實現壓縮和解壓

  本文檔基於ICSharpCode.SharpZipLib.dll的封裝,經常使用的解壓和壓縮方法都已經涵蓋在內,都是通過項目實戰積累下來的html

1.基本介紹

因爲項目中須要用到各類壓縮將文件進行壓縮下載,減小網絡的帶寬,因此壓縮是一個很是常見的功能,對於壓縮微軟本身也提供了一些類庫c#

  1. 微軟自帶壓縮類ZipArchive類,適合NET FrameWork4.5纔可使用
  2. 調用壓縮軟件命令執行壓縮動做,這個就須要電腦自己安裝壓縮軟件了
  3. 使用第三方的壓縮dll文件,通常使用最多的是(ICSharpCode.SharpZipLib.dll),下載dll ICSharpCode.SharpZipLib.zip

本文使用的正是ICSharpCode.SharpZipLib.dll相關的dll,ZipArchive相關的壓縮和解壓縮,後續會慢慢補上的。網絡

2.實際項目

  1. 壓縮單個文件,須要指定壓縮等級
  2. 壓縮單個文件夾,須要指定壓縮等級
  3. 壓縮多個文件或者多個文件夾
  4. 對壓縮包進行加密【用的較少,實際狀況也有】
  5. 直接解壓,無需密碼
  6. 須要密碼解壓

2.1 壓縮單個文件

寫了兩個方法,能夠指定壓縮等級,這樣你的壓縮包大小就不同了

2.2 壓縮單個文件夾

public void ZipDir(string dirToZip, string zipedFileName, int compressionLevel = 9)

 

2.3 壓縮多個文件或者文件夾

public bool ZipManyFilesOrDictorys(IEnumerable<string> folderOrFileList, string zipedFile, string password)

 

2.4 對壓縮包進行加密

public bool ZipManyFilesOrDictorys(IEnumerable<string> folderOrFileList, string zipedFile, string password)

 

2.5 直接解壓,無需密碼

public void UnZip(string zipFilePath, string unZipDir)

3.演示圖

3.ZipHelper下載

//-------------------------------------------------------------------------------------
// All Rights Reserved , Copyright (C) 2016 , ZTO , Ltd .
//-------------------------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

namespace ZTO.PicTest.Utilities
{
    using ICSharpCode.SharpZipLib.Checksums;
    using ICSharpCode.SharpZipLib.Zip;

    /// <summary>
    /// Zip壓縮幫助類
    ///
    /// 修改紀錄
    ///
    ///        2015-09-16  版本:1.0 YangHengLian 建立主鍵,注意命名空間的排序。
    ///     2016-5-7 YangHengLian增長了能夠支持多個文件或者多個文件夾打包成一個zip文件
    /// 
    /// 版本:1.0
    ///
    /// <author>
    ///        <name>YangHengLian</name>
    ///        <date>2015-09-16</date>
    /// </author>
    /// </summary>
    public class ZipHelper
    {
        /// <summary>
        /// 壓縮文件夾
        /// </summary>
        /// <param name="dirToZip"></param>
        /// <param name="zipedFileName"></param>
        /// <param name="compressionLevel">壓縮率0(無壓縮)9(壓縮率最高)</param>
        public void ZipDir(string dirToZip, string zipedFileName, int compressionLevel = 9)
        {
            if (Path.GetExtension(zipedFileName) != ".zip")
            {
                zipedFileName = zipedFileName + ".zip";
            }
            using (var zipoutputstream = new ZipOutputStream(File.Create(zipedFileName)))
            {
                zipoutputstream.SetLevel(compressionLevel);
                Crc32 crc = new Crc32();
                Hashtable fileList = GetAllFies(dirToZip);
                foreach (DictionaryEntry item in fileList)
                {
                    FileStream fs = new FileStream(item.Key.ToString(), FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, buffer.Length);
                    // ZipEntry entry = new ZipEntry(item.Key.ToString().Substring(dirToZip.Length + 1));
                    ZipEntry entry = new ZipEntry(Path.GetFileName(item.Key.ToString()))
                                     {
                                         DateTime = (DateTime) item.Value,
                                         Size = fs.Length
                                     };
                    fs.Close();
                    crc.Reset();
                    crc.Update(buffer);
                    entry.Crc = crc.Value;
                    zipoutputstream.PutNextEntry(entry);
                    zipoutputstream.Write(buffer, 0, buffer.Length);
                }
            }
        }

        /// <summary>  
        /// 獲取全部文件  
        /// </summary>  
        /// <returns></returns>  
        public Hashtable GetAllFies(string dir)
        {
            Hashtable filesList = new Hashtable();
            DirectoryInfo fileDire = new DirectoryInfo(dir);
            if (!fileDire.Exists)
            {
                throw new FileNotFoundException("目錄:" + fileDire.FullName + "沒有找到!");
            }

            GetAllDirFiles(fileDire, filesList);
            GetAllDirsFiles(fileDire.GetDirectories(), filesList);
            return filesList;
        }

        /// <summary>  
        /// 獲取一個文件夾下的全部文件夾裏的文件  
        /// </summary>  
        /// <param name="dirs"></param>  
        /// <param name="filesList"></param>  
        public void GetAllDirsFiles(IEnumerable<DirectoryInfo> dirs, Hashtable filesList)
        {
            foreach (DirectoryInfo dir in dirs)
            {
                foreach (FileInfo file in dir.GetFiles("*.*"))
                {
                    filesList.Add(file.FullName, file.LastWriteTime);
                }
                GetAllDirsFiles(dir.GetDirectories(), filesList);
            }
        }

        /// <summary>  
        /// 獲取一個文件夾下的文件  
        /// </summary>  
        /// <param name="dir">目錄名稱</param>
        /// <param name="filesList">文件列表HastTable</param>  
        public static void GetAllDirFiles(DirectoryInfo dir, Hashtable filesList)
        {
            foreach (FileInfo file in dir.GetFiles("*.*"))
            {
                filesList.Add(file.FullName, file.LastWriteTime);
            }
        }

        /// <summary>  
        /// 功能:解壓zip格式的文件。  
        /// </summary>  
        /// <param name="zipFilePath">壓縮文件路徑</param>  
        /// <param name="unZipDir">解壓文件存放路徑,爲空時默認與壓縮文件同一級目錄下,跟壓縮文件同名的文件夾</param>  
        /// <returns>解壓是否成功</returns>  
        public void UnZip(string zipFilePath, string unZipDir)
        {
            if (zipFilePath == string.Empty)
            {
                throw new Exception("壓縮文件不能爲空!");
            }
            if (!File.Exists(zipFilePath))
            {
                throw new FileNotFoundException("壓縮文件不存在!");
            }
            //解壓文件夾爲空時默認與壓縮文件同一級目錄下,跟壓縮文件同名的文件夾  
            if (unZipDir == string.Empty)
                unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
            if (!unZipDir.EndsWith("/"))
                unZipDir += "/";
            if (!Directory.Exists(unZipDir))
                Directory.CreateDirectory(unZipDir);

            using (var s = new ZipInputStream(File.OpenRead(zipFilePath)))
            {

                ZipEntry theEntry;
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    string directoryName = Path.GetDirectoryName(theEntry.Name);
                    string fileName = Path.GetFileName(theEntry.Name);
                    if (!string.IsNullOrEmpty(directoryName))
                    {
                        Directory.CreateDirectory(unZipDir + directoryName);
                    }
                    if (directoryName != null && !directoryName.EndsWith("/"))
                    {
                    }
                    if (fileName != String.Empty)
                    {
                        using (FileStream streamWriter = File.Create(unZipDir + theEntry.Name))
                        {

                            int size;
                            byte[] data = new byte[2048];
                            while (true)
                            {
                                size = s.Read(data, 0, data.Length);
                                if (size > 0)
                                {
                                    streamWriter.Write(data, 0, size);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 壓縮單個文件
        /// </summary>
        /// <param name="filePath">被壓縮的文件名稱(包含文件路徑),文件的全路徑</param>
        /// <param name="zipedFileName">壓縮後的文件名稱(包含文件路徑),保存的文件名稱</param>
        /// <param name="compressionLevel">壓縮率0(無壓縮)到 9(壓縮率最高)</param>
        public void ZipFile(string filePath, string zipedFileName, int compressionLevel = 9)
        {
            // 若是文件沒有找到,則報錯 
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException("文件:" + filePath + "沒有找到!");
            }
            // 若是壓縮後名字爲空就默認使用源文件名稱做爲壓縮文件名稱
            if (string.IsNullOrEmpty(zipedFileName))
            {
                string oldValue = Path.GetFileName(filePath);
                if (oldValue != null)
                {
                    zipedFileName = filePath.Replace(oldValue, "") + Path.GetFileNameWithoutExtension(filePath) + ".zip";
                }
            }
            // 若是壓縮後的文件名稱後綴名不是zip,就是加上zip,防止是一個亂碼文件
            if (Path.GetExtension(zipedFileName) != ".zip")
            {
                zipedFileName = zipedFileName + ".zip";
            }
            // 若是指定位置目錄不存在,建立該目錄  C:\Users\yhl\Desktop\大漢三通
            string zipedDir = zipedFileName.Substring(0, zipedFileName.LastIndexOf("\\", StringComparison.Ordinal));
            if (!Directory.Exists(zipedDir))
            {
                Directory.CreateDirectory(zipedDir);
            }
            // 被壓縮文件名稱
            string filename = filePath.Substring(filePath.LastIndexOf("\\", StringComparison.Ordinal) + 1);
            var streamToZip = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            var zipFile = File.Create(zipedFileName);
            var zipStream = new ZipOutputStream(zipFile);
            var zipEntry = new ZipEntry(filename);
            zipStream.PutNextEntry(zipEntry);
            zipStream.SetLevel(compressionLevel);
            var buffer = new byte[2048];
            Int32 size = streamToZip.Read(buffer, 0, buffer.Length);
            zipStream.Write(buffer, 0, size);
            try
            {
                while (size < streamToZip.Length)
                {
                    int sizeRead = streamToZip.Read(buffer, 0, buffer.Length);
                    zipStream.Write(buffer, 0, sizeRead);
                    size += sizeRead;
                }
            }
            finally
            {
                zipStream.Finish();
                zipStream.Close();
                streamToZip.Close();
            }
        }

        /// <summary> 
        /// 壓縮單個文件 
        /// </summary> 
        /// <param name="fileToZip">要進行壓縮的文件名,全路徑</param> 
        /// <param name="zipedFile">壓縮後生成的壓縮文件名,全路徑</param> 
        public void ZipFile(string fileToZip, string zipedFile)
        {
            // 若是文件沒有找到,則報錯 
            if (!File.Exists(fileToZip))
            {
                throw new FileNotFoundException("指定要壓縮的文件: " + fileToZip + " 不存在!");
            }
            using (FileStream fileStream = File.OpenRead(fileToZip))
            {
                byte[] buffer = new byte[fileStream.Length];
                fileStream.Read(buffer, 0, buffer.Length);
                fileStream.Close();
                using (FileStream zipFile = File.Create(zipedFile))
                {
                    using (ZipOutputStream zipOutputStream = new ZipOutputStream(zipFile))
                    {
                        // string fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\") + 1);
                        string fileName = Path.GetFileName(fileToZip);
                        var zipEntry = new ZipEntry(fileName)
                        {
                            DateTime = DateTime.Now,
                            IsUnicodeText = true
                        };
                        zipOutputStream.PutNextEntry(zipEntry);
                        zipOutputStream.SetLevel(5);
                        zipOutputStream.Write(buffer, 0, buffer.Length);
                        zipOutputStream.Finish();
                        zipOutputStream.Close();
                    }
                }
            }
        }

        /// <summary>
        /// 壓縮多個目錄或文件
        /// </summary>
        /// <param name="folderOrFileList">待壓縮的文件夾或者文件,全路徑格式,是一個集合</param>
        /// <param name="zipedFile">壓縮後的文件名,全路徑格式</param>
        /// <param name="password">壓宿密碼</param>
        /// <returns></returns>
        public bool ZipManyFilesOrDictorys(IEnumerable<string> folderOrFileList, string zipedFile, string password)
        {
            bool res = true;
            using (var s = new ZipOutputStream(File.Create(zipedFile)))
            {
                s.SetLevel(6);
                if (!string.IsNullOrEmpty(password))
                {
                    s.Password = password;
                }
                foreach (string fileOrDir in folderOrFileList)
                {
                    //是文件夾
                    if (Directory.Exists(fileOrDir))
                    {
                        res = ZipFileDictory(fileOrDir, s, "");
                    }
                    else
                    {
                        //文件
                        res = ZipFileWithStream(fileOrDir, s);
                    }
                }
                s.Finish();
                s.Close();
                return res;
            }
        }

        /// <summary>
        /// 帶壓縮流壓縮單個文件
        /// </summary>
        /// <param name="fileToZip">要進行壓縮的文件名</param>
        /// <param name="zipStream"></param>
        /// <returns></returns>
        private bool ZipFileWithStream(string fileToZip, ZipOutputStream zipStream)
        {
            //若是文件沒有找到,則報錯
            if (!File.Exists(fileToZip))
            {
                throw new FileNotFoundException("指定要壓縮的文件: " + fileToZip + " 不存在!");
            }
            //FileStream fs = null;
            FileStream zipFile = null;
            ZipEntry zipEntry = null;
            bool res = true;
            try
            {
                zipFile = File.OpenRead(fileToZip);
                byte[] buffer = new byte[zipFile.Length];
                zipFile.Read(buffer, 0, buffer.Length);
                zipFile.Close();
                zipEntry = new ZipEntry(Path.GetFileName(fileToZip));
                zipStream.PutNextEntry(zipEntry);
                zipStream.Write(buffer, 0, buffer.Length);
            }
            catch
            {
                res = false;
            }
            finally
            {
                if (zipEntry != null)
                {
                }

                if (zipFile != null)
                {
                    zipFile.Close();
                }
                GC.Collect();
                GC.Collect(1);
            }
            return res;

        }

        /// <summary>
        /// 遞歸壓縮文件夾方法
        /// </summary>
        /// <param name="folderToZip"></param>
        /// <param name="s"></param>
        /// <param name="parentFolderName"></param>
        private bool ZipFileDictory(string folderToZip, ZipOutputStream s, string parentFolderName)
        {
            bool res = true;
            ZipEntry entry = null;
            FileStream fs = null;
            Crc32 crc = new Crc32();
            try
            {
                //建立當前文件夾
                entry = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/")); //加上 「/」 纔會當成是文件夾建立
                s.PutNextEntry(entry);
                s.Flush();
                //先壓縮文件,再遞歸壓縮文件夾
                var filenames = Directory.GetFiles(folderToZip);
                foreach (string file in filenames)
                {
                    //打開壓縮文件
                    fs = File.OpenRead(file);
                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, buffer.Length);
                    entry = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/" + Path.GetFileName(file)));
                    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);
                }
            }
            catch
            {
                res = false;
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
                if (entry != null)
                {
                }
                GC.Collect();
                GC.Collect(1);
            }
            var folders = Directory.GetDirectories(folderToZip);
            foreach (string folder in folders)
            {
                if (!ZipFileDictory(folder, s, Path.Combine(parentFolderName, Path.GetFileName(folderToZip))))
                {
                    return false;
                }
            }
            return res;
        }
    }
}
ZipHelper

 

 

出處:https://www.cnblogs.com/weixing/p/5478845.htmlide

相關文章
相關標籤/搜索