C#基礎知識之SharpZipLib壓縮解壓的使用


項目中使用 Velocity 將模板和生成的動態內容(HTML、XML等)合並保存到redis數據庫中,考慮到壓縮的文件容量會比較小,方便傳輸而且存儲所使用的空間也會比較小,所以要壓縮一下,讀取的時候也要解壓,所以就用到了SharpZipLib。SharpZipLib是一個完全用c#為. net平台編寫的Zip、GZip、Tar和BZip2庫。官網代碼下載https://github.com/icsharpcode/SharpZipLib。如果要使用SharpZipLib,我們可以直接下載源碼引入項目,也可以下載SharpZLib.dll。SharpZLib.dll可以從網上下載也可以通過代碼自己生成dill。

  壓縮分為無損壓縮和有損壓縮,有損壓縮指的是壓縮之后就無法完整還原原始信息,但是壓縮率可以很高,主要應用於視頻、話音等數據的壓縮,如果沒必要完整還原信息,可以使用有損壓縮,僅僅損失了一點信息,很難察覺;無損壓縮則用於文件等等必須完整還原信息的場合,常見的無損壓縮包括Zip、GZip、RAR、Tar、BZip2等。

一、如何使用SharpZipLib

  1、項目中引用SharpZLib.dll

  2、本項目中,單獨寫了一個ZipHelper類,用來使用SharpZipLib中封裝的壓縮方式。zipHelper類時可以作為使用Zip、Tar、GZip、Lzw、BZip2壓縮方式的入口。直接上ZipHelper類的代碼吧   

using SharpZipLib.BZip2;
using SharpZipLib.Checksum;
using SharpZipLib.Core.Exceptions;
using SharpZipLib.GZip;
using SharpZipLib.Tar;
using SharpZipLib.Zip;
using SharpZipLib.Zip.Compression;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace SharpZipLibExample
{
    /// <summary>
    /// 網上關於壓縮的知識很多
    /// https://www.cnblogs.com/kissdodog/p/3525295.html
    /// </summary>
    public class ZipHelper
    {
        private const int BUFFER_LENGTH = 2048;
        #region Zip  
        /// <summary>
        /// Zip文件壓縮
        /// ZipOutputStream:相當於一個壓縮包;
        /// ZipEntry:相當於壓縮包里的一個文件;
        /// 以上兩個類是SharpZipLib的主類。
        /// </summary>
        /// <param name="sourceFileLists"></param>
        /// <param name="descFile">壓縮文件保存的目錄</param>
        /// <param name="compression">壓縮級別</param>
        public static void ZipCompress(List<string> sourceFileLists, string descFile, int compression)
        {
            if (compression < 0 || compression > 9)
            {
                throw new ArgumentException("錯誤的壓縮級別");
            }
            if (!Directory.Exists(new FileInfo(descFile).Directory.ToString()))
            {
                throw new ArgumentException("保存目錄不存在");
            }
            foreach (string c in sourceFileLists)
            {
                if (!File.Exists(c))
                {
                    throw new ArgumentException(string.Format("文件{0} 不存在!", c));
                }
            }
            Crc32 crc32 = new Crc32();
            using (ZipOutputStream stream = new ZipOutputStream(File.Create(descFile)))
            {
                stream.SetLevel(compression);
                ZipEntry entry;
                for (int i = 0; i < sourceFileLists.Count; i++)
                {
                    entry = new ZipEntry(Path.GetFileName(sourceFileLists[i]));
                    entry.DateTime = DateTime.Now;
                    using (FileStream fs = File.OpenRead(sourceFileLists[i]))
                    {
                        byte[] buffer = new byte[fs.Length];
                        fs.Read(buffer, 0, buffer.Length);
                        entry.Size = fs.Length;
                        crc32.Reset();
                        crc32.Update(buffer);
                        entry.Crc = crc32.Value;
                        stream.PutNextEntry(entry);
                        stream.Write(buffer, 0, buffer.Length);
                    }
                    stream.CloseEntry();
                }

            }
        }
        /// <summary>
        /// unZip文件解壓縮
        /// </summary>
        /// <param name="sourceFile">要解壓的文件</param>
        /// <param name="path">要解壓到的目錄</param>
        public static void ZipDeCompress(string sourceFile, string path)
        {
            if (!File.Exists(sourceFile))
            {
                throw new ArgumentException("要解壓的文件不存在。");
            }
            if (!Directory.Exists(path))
            {
                throw new ArgumentException("要解壓到的目錄不存在!");
            }
            using (ZipInputStream s = new ZipInputStream(File.OpenRead(sourceFile)))
            {
                ZipEntry theEntry;
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    string fileName = System.IO.Path.GetFileName(theEntry.Name);
                    if (fileName != string.Empty)
                    {
                        using (FileStream streamWriter = File.Create(path + @"\" + theEntry.Name))
                        {
                            int size = 2048;
                            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="text">待壓縮的字符串</param>
        /// <returns>已壓縮的字符串</returns>
        public static string ZipCompress(string text)
        {
            string result = string.Empty;
            byte[] data = Encoding.UTF8.GetBytes(text);
            byte[] dData = ZipCompress(data);
            result = Convert.ToBase64String(dData);
            Array.Clear(dData, 0, dData.Length);
            return result;
        }
        /// <summary>
        /// 字符串解壓
        /// </summary>
        /// <param name="text">待解壓的字符串</param>
        /// <returns>已解壓的字符串</returns>
        public static string ZipDeCompress(string text)
        {
            string result = string.Empty;
            byte[] data = Convert.FromBase64String(text);
            byte[] dData = ZipDeCompress(data);
            result = Encoding.UTF8.GetString(dData);
            Array.Clear(dData,0,dData.Length);
            return result;
        }
        /// <summary>
        /// 字節數組壓縮
        /// </summary>
        /// <param name="data">待壓縮的字節數組</param>
        /// <param name="isClearData">壓縮完成后,是否清除待壓縮字節數組里面的內容</param>
        /// <returns>已壓縮的字節數組</returns>
        public static byte[] ZipCompress(byte[] data, bool isClearData = true)
        {
            byte[] bytes = null;
            Deflater f = new Deflater(Deflater.BEST_COMPRESSION);
            f.SetInput(data);
            f.Finish();
            int count = 0;
            using (MemoryStream o=new MemoryStream(data.Length))
            {
                byte[] buffer = new byte[BUFFER_LENGTH];
                while (!f.IsFinished)
                {
                    count = f.Deflate(buffer);
                    o.Write(buffer,0,count);
                }
                bytes = o.ToArray();
            }
            if (isClearData)
            {
                Array.Clear(data,0,data.Length);
            }
            return bytes;
        }
        /// <summary>
        /// 字節數組解壓縮
        /// </summary>
        /// <param name="data">待解壓縮的字節數組</param>
        /// <param name="isClearData">解壓縮完成后,是否清除待解壓縮字節數組里面的內容</param>
        /// <returns>已解壓的字節數組</returns>
        public static byte[] ZipDeCompress(byte[] data, bool isClearData = true)
        {
            byte[] bytes = null;
            Inflater f = new Inflater();
            f.SetInput(data);
            int count = 0;
            using (MemoryStream o=new MemoryStream(data.Length))
            {
                byte[] buffer = new byte[BUFFER_LENGTH];
                while (!f.IsFinished)
                {
                    count = f.Inflate(buffer);
                    o.Write(buffer,0,count);
                }
                bytes = o.ToArray();
            }
            if (isClearData)
            {
                Array.Clear(data,0,count);
            }
            return bytes;
        }
        #endregion

        #region GZip
        /// <summary>
        /// 壓縮字符串
        /// </summary>
        /// <param name="text">待壓縮的字符串組</param>
        /// <returns>已壓縮的字符串</returns>
        public static string GZipCompress(string text)
        {
            string result = string.Empty;
            byte[] data = Encoding.UTF8.GetBytes(text);
            byte[] cData = GZipCompress(data);
            result = Convert.ToBase64String(cData);
            Array.Clear(cData, 0, cData.Length);
            return result;
        }
        /// <summary>
        /// 解壓縮字符串
        /// </summary>
        /// <param name="text">待解壓縮的字符串</param>
        /// <returns>已解壓縮的字符串</returns>
        public static string GZipDeCompress(string text)
        {
            string result = string.Empty;
            byte[] data = Convert.FromBase64String(text);
            byte[] cData = GZipDeCompress(data);
            result = Encoding.UTF8.GetString(cData);
            Array.Clear(cData, 0, cData.Length);
            return result;
        }
        /// <summary>
        /// 壓縮字節數組
        /// </summary>
        /// <param name="data">待壓縮的字節數組</param>
        /// <param name="isClearData">壓縮完成后,是否清除待壓縮字節數組里面的內容</param>
        /// <returns>已壓縮的字節數組</returns>
        public static byte[] GZipCompress(byte[] data, bool isClearData = true)
        {
            byte[] bytes = null;
            try
            {
                using (MemoryStream o = new MemoryStream())
                {
                    using (Stream s = new GZipOutputStream(o))
                    {
                        s.Write(data, 0, data.Length);
                        s.Flush();
                    }
                    bytes = o.ToArray();
                }
            }
            catch (SharpZipBaseException)
            {
            }
            catch (IndexOutOfRangeException)
            {
            }
            if (isClearData)
                Array.Clear(data, 0, data.Length);
            return bytes;
        }

        /// <summary>
        /// 解壓縮字節數組
        /// </summary>
        /// <param name="data">待解壓縮的字節數組</param>
        /// <param name="isClearData">解壓縮完成后,是否清除待解壓縮字節數組里面的內容</param>
        /// <returns>已解壓的字節數組</returns>
        public static byte[] GZipDeCompress(byte[] data, bool isClearData = true)
        {
            byte[] bytes = null;
            try
            {
                using (MemoryStream o = new MemoryStream())
                {
                    using (MemoryStream ms = new MemoryStream(data))
                    {
                        using (Stream s = new GZipInputStream(ms))
                        {
                            s.Flush();
                            int size = 0;
                            byte[] buffer = new byte[BUFFER_LENGTH];
                            while ((size = s.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                o.Write(buffer, 0, size);
                            }
                        }
                    }
                    bytes = o.ToArray();
                }
            }
            catch (SharpZipBaseException)
            {
            }
            catch (IndexOutOfRangeException)
            {
            }
            if (isClearData)
                Array.Clear(data, 0, data.Length);
            return bytes;
        }
        #endregion

        #region Tar
        /// <summary>
        /// 壓縮字符串
        /// </summary>
        /// <param name="text">待壓縮的字符串組</param>
        /// <returns>已壓縮的字符串</returns>
        public static string TarCompress(string text)
        {
            string result = null;
            byte[] data = Encoding.UTF8.GetBytes(text);
            byte[] dData = TarCompress(data);
            result = Convert.ToBase64String(dData);
            Array.Clear(dData, 0, dData.Length);
            return result;
        }
        /// <summary>
        /// 解壓縮字符串
        /// </summary>
        /// <param name="text">待解壓縮的字符串</param>
        /// <returns>已解壓的字符串</returns>
        public static string TarDeCompress(string text)
        {
            string result = null;
            byte[] data = Convert.FromBase64String(text);
            byte[] dData = TarDeCompress(data);
            result = Encoding.UTF8.GetString(dData);
            Array.Clear(dData, 0, dData.Length);
            return result;
        }
        /// <summary>
        /// 壓縮字節數組
        /// </summary>
        /// <param name="data">待壓縮的字節數組</param>
        /// <param name="isClearData">壓縮完成后,是否清除待壓縮字節數組里面的內容</param>
        /// <returns>已壓縮的字節數組</returns>
        public static byte[] TarCompress(byte[] data, bool isClearData = true)
        {
            byte[] bytes = null;
            using (MemoryStream o = new MemoryStream())
            {
                using (Stream s = new TarOutputStream(o))
                {
                    s.Write(data, 0, data.Length);
                    s.Flush();
                }
                bytes = o.ToArray();
            }
            if (isClearData)
                Array.Clear(data, 0, data.Length);
            return bytes;
        }
        /// <summary>
        /// 解壓縮字節數組
        /// </summary>
        /// <param name="data">待解壓縮的字節數組</param>
        /// <param name="isClearData">解壓縮完成后,是否清除待解壓縮字節數組里面的內容</param>
        /// <returns>已解壓的字節數組</returns>
        public static byte[] TarDeCompress(byte[] data, bool isClearData = true)
        {
            byte[] bytes = null;
            using (MemoryStream o = new MemoryStream())
            {
                using (MemoryStream ms = new MemoryStream(data))
                {
                    using (Stream s = new TarInputStream(ms))
                    {
                        s.Flush();
                        int size = 0;
                        byte[] buffer = new byte[BUFFER_LENGTH];
                        while ((size = s.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            o.Write(buffer, 0, size);
                        }
                    }
                }
                bytes = o.ToArray();
            }
            if (isClearData)
                Array.Clear(data, 0, data.Length);
            return bytes;
        }
        #endregion

        #region BZip
        /// <summary>
        /// 壓縮字符串
        /// </summary>
        /// <param name="text">待壓縮的字符串組</param>
        /// <returns>已壓縮的字符串</returns>
        public static string BZipCompress(string text)
        {
            string result = null;
            byte[] data = Encoding.UTF8.GetBytes(text);
            byte[] dData = BZipCompress(data);
            result = Convert.ToBase64String(dData);
            Array.Clear(dData, 0, dData.Length);
            return result;
        }
        /// <summary>
        /// 解壓縮字符串
        /// </summary>
        /// <param name="text">待解壓縮的字符串</param>
        /// <returns>已解壓的字符串</returns>
        public static string BZipDeCompress(string text)
        {
            string result = null;
            byte[] data = Convert.FromBase64String(text);
            byte[] dData = BZipDeCompress(data);
            result = Encoding.UTF8.GetString(dData);
            Array.Clear(dData, 0, dData.Length);
            return result;
        }
        /// <summary>
        /// 壓縮字節數組
        /// </summary>
        /// <param name="data">待壓縮的字節數組</param>
        /// <param name="isClearData">壓縮完成后,是否清除待壓縮字節數組里面的內容</param>
        /// <returns>已壓縮的字節數組</returns>
        public static byte[] BZipCompress(byte[] data, bool isClearData = true)
        {
            byte[] bytes = null;
            using (MemoryStream o = new MemoryStream())
            {
                using (Stream s = new BZip2OutputStream(o))
                {
                    s.Write(data, 0, data.Length);
                    s.Flush();
                }
                bytes = o.ToArray();
            }
            if (isClearData)
                Array.Clear(data, 0, data.Length);
            return bytes;
        }
        /// <summary>
        /// 解壓縮字節數組
        /// </summary>
        /// <param name="data">待解壓縮的字節數組</param>
        /// <param name="isClearData">解壓縮完成后,是否清除待解壓縮字節數組里面的內容</param>
        /// <returns>已解壓的字節數組</returns>
        public static byte[] BZipDeCompress(byte[] data, bool isClearData = true)
        {
            byte[] bytes = null;
            using (MemoryStream o = new MemoryStream())
            {
                using (MemoryStream ms = new MemoryStream(data))
                {
                    using (Stream s = new BZip2InputStream(ms))
                    {
                        s.Flush();
                        int size = 0;
                        byte[] buffer = new byte[BUFFER_LENGTH];
                        while ((size = s.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            o.Write(buffer, 0, size);
                        }
                    }
                }
                bytes = o.ToArray();
            }
            if (isClearData)
                Array.Clear(data, 0, data.Length);
            return bytes;
        }
        #endregion
    }
}
View Code

 

  3、程序入口main  

using System;
using System.Linq;
using System.Text;

namespace SharpZipLibExample
{
    class Program
    {
        static void Main(string[] args)
        {
            string strContent = "夜,結束了一天的喧囂后安靜下來,伴隨着遠處路燈那微弱的光。風,毫無預兆地席卷整片曠野,撩動人的思緒萬千。星,遙遙地掛在天空之中,閃爍着它那微微星光,不如陽光般燦爛卻如花兒般如痴如醉。";
            Console.WriteLine("原文:{0}",strContent);
            #region 壓縮
            string compressContent = ZipHelper.BZipCompress(strContent);
            Console.WriteLine("壓縮后的內容:{0};壓縮后的內容大小:{1}", compressContent, Convert.FromBase64String(compressContent).Count().ToString());
            #endregion

            #region 解壓縮
            strContent = ZipHelper.BZipDeCompress(compressContent);
            Console.WriteLine("解壓縮后的內容:{0};解壓縮后的內容大小:{1}", strContent,Encoding.UTF8.GetBytes(strContent).Count().ToString());
            #endregion
            Console.ReadKey();      
        }
    }
}  
View Code

 

SharpZipLib的詳細解析詳見 https://www.cnblogs.com/kissdodog/p/3525295.html

完整的Demo下載地址https://download.csdn.net/download/u011392711/10827889

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM