項目中使用 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 } }
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(); } } }
SharpZipLib的詳細解析詳見 https://www.cnblogs.com/kissdodog/p/3525295.html
完整的Demo下載地址https://download.csdn.net/download/u011392711/10827889