C#中ZipHelper 壓縮和解壓幫助類(lèi)
關(guān)于本文檔的說(shuō)明
本文檔基于ICSharpCode.SharpZipLib.dll的封裝,常用的解壓和壓縮方法都已經(jīng)涵蓋在內(nèi),都是經(jīng)過(guò)項(xiàng)目實(shí)戰(zhàn)積累下來(lái)的
歡迎傳播分享,必須保持原作者的信息,但禁止將該文檔直接用于商業(yè)盈利。
本人自從幾年前走上編程之路,一直致力于收集和總結(jié)出好用的框架和通用類(lèi)庫(kù),不管是微軟自己的還是第三方的只要實(shí)際項(xiàng)目中好用且可以解決實(shí)際問(wèn)題那都會(huì)收集好,編寫(xiě)好文章和別人一起分享,這樣自己學(xué)到了,別人也能學(xué)到知識(shí),當(dāng)今社會(huì)很需要知識(shí)的搬運(yùn)工。
1.基本介紹
由于項(xiàng)目中需要用到各種壓縮將文件進(jìn)行壓縮下載,減少網(wǎng)絡(luò)的帶寬,所以壓縮是一個(gè)非常常見(jiàn)的功能,對(duì)于壓縮微軟自己也提供了一些類(lèi)庫(kù)
微軟自帶壓縮類(lèi)ZipArchive類(lèi),適合NET FrameWork4.5才可以使用
調(diào)用壓縮軟件命令執(zhí)行壓縮動(dòng)作,這個(gè)就需要電腦本身安裝壓縮軟件了
使用第三方的壓縮dll文件,一般使用最多的是(ICSharpCode.SharpZipLib.dll),下載dll ICSharpCode.SharpZipLib.zip
2.實(shí)際項(xiàng)目
壓縮單個(gè)文件,需要指定壓縮等級(jí)
壓縮單個(gè)文件夾,需要指定壓縮等級(jí)
壓縮多個(gè)文件或者多個(gè)文件夾
對(duì)壓縮包進(jìn)行加密【用的較少,實(shí)際情況也有】
2.1 壓縮單個(gè)文件
寫(xiě)了兩個(gè)方法,可以指定壓縮等級(jí),這樣你的壓縮包大小就不一樣了
2.2 壓縮單個(gè)文件夾
public void ZipDir(string dirToZip, string zipedFileName, int compressionLevel = 9)
2.3 壓縮多個(gè)文件或者文件夾
public bool ZipManyFilesOrDictorys(IEnumerable<string> folderOrFileList, string zipedFile, string password)
2.4 對(duì)壓縮包進(jìn)行加密
public bool ZipManyFilesOrDictorys(IEnumerable<string> folderOrFileList, string zipedFile, string password)
2.5 直接解壓,無(wú)需密碼
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壓縮幫助類(lèi) /// /// 修改紀(jì)錄 /// /// 2015-09-16 版本:1.0 YangHengLian 創(chuàng)建主鍵,注意命名空間的排序。 /// 2016-5-7 YangHengLian增加了可以支持多個(gè)文件或者多個(gè)文件夾打包成一個(gè)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(無(wú)壓縮)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 + "沒(méi)有找到!"); } GetAllDirFiles(fileDire, filesList); GetAllDirsFiles(fileDire.GetDirectories(), filesList); return filesList; } /// <summary> /// 獲取一個(gè)文件夾下的所有文件夾里的文件 /// </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> /// 獲取一個(gè)文件夾下的文件 /// </summary> /// <param name="dir">目錄名稱(chēng)</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">解壓文件存放路徑,為空時(shí)默認(rèn)與壓縮文件同一級(jí)目錄下,跟壓縮文件同名的文件夾</param> /// <returns>解壓是否成功</returns> public void UnZip(string zipFilePath, string unZipDir) { if (zipFilePath == string.Empty) { throw new Exception("壓縮文件不能為空!"); } if (!File.Exists(zipFilePath)) { throw new FileNotFoundException("壓縮文件不存在!"); } //解壓文件夾為空時(shí)默認(rèn)與壓縮文件同一級(jí)目錄下,跟壓縮文件同名的文件夾 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> /// 壓縮單個(gè)文件 /// </summary> /// <param name="filePath">被壓縮的文件名稱(chēng)(包含文件路徑),文件的全路徑</param> /// <param name="zipedFileName">壓縮后的文件名稱(chēng)(包含文件路徑),保存的文件名稱(chēng)</param> /// <param name="compressionLevel">壓縮率0(無(wú)壓縮)到 9(壓縮率最高)</param> public void ZipFile(string filePath, string zipedFileName, int compressionLevel = 9) { // 如果文件沒(méi)有找到,則報(bào)錯(cuò) if (!File.Exists(filePath)) { throw new FileNotFoundException("文件:" + filePath + "沒(méi)有找到!"); } // 如果壓縮后名字為空就默認(rèn)使用源文件名稱(chēng)作為壓縮文件名稱(chēng) if (string.IsNullOrEmpty(zipedFileName)) { string oldValue = Path.GetFileName(filePath); if (oldValue != null) { zipedFileName = filePath.Replace(oldValue, "") + Path.GetFileNameWithoutExtension(filePath) + ".zip"; } } // 如果壓縮后的文件名稱(chēng)后綴名不是zip,就是加上zip,防止是一個(gè)亂碼文件 if (Path.GetExtension(zipedFileName) != ".zip") { zipedFileName = zipedFileName + ".zip"; } // 如果指定位置目錄不存在,創(chuàng)建該目錄 C:\Users\yhl\Desktop\大漢三通 string zipedDir = zipedFileName.Substring(0, zipedFileName.LastIndexOf("\\", StringComparison.Ordinal)); if (!Directory.Exists(zipedDir)) { Directory.CreateDirectory(zipedDir); } // 被壓縮文件名稱(chēng) 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> /// 壓縮單個(gè)文件 /// </summary> /// <param name="fileToZip">要進(jìn)行壓縮的文件名,全路徑</param> /// <param name="zipedFile">壓縮后生成的壓縮文件名,全路徑</param> public void ZipFile(string fileToZip, string zipedFile) { // 如果文件沒(méi)有找到,則報(bào)錯(cuò) 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> /// 壓縮多個(gè)目錄或文件 /// </summary> /// <param name="folderOrFileList">待壓縮的文件夾或者文件,全路徑格式,是一個(gè)集合</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> /// 帶壓縮流壓縮單個(gè)文件 /// </summary> /// <param name="fileToZip">要進(jìn)行壓縮的文件名</param> /// <param name="zipStream"></param> /// <returns></returns> private bool ZipFileWithStream(string fileToZip, ZipOutputStream zipStream) { //如果文件沒(méi)有找到,則報(bào)錯(cuò) 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 { //創(chuàng)建當(dāng)前文件夾 entry = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/")); //加上 “/” 才會(huì)當(dāng)成是文件夾創(chuàng)建 s.PutNextEntry(entry); s.Flush(); //先壓縮文件,再遞歸壓縮文件夾 var filenames = Directory.GetFiles(folderToZip); foreach (string file in filenames) { //打開(kāi)壓縮文件 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; } } }
慢慢積累,你的這些代碼都是你的財(cái)富,可以幫你提高工作效率,勤勤懇懇的干好每件事情,點(diǎn)滴積累,開(kāi)心編程。
上一篇:C# MVC模式下商品抽獎(jiǎng)功能實(shí)現(xiàn)
欄 目:C#教程
下一篇:C# JsonHelper 操作輔助類(lèi),拿來(lái)直接用
本文標(biāo)題:C#中ZipHelper 壓縮和解壓幫助類(lèi)
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/6543.html
您可能感興趣的文章
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并打開(kāi)的方法
- 01-10C#實(shí)現(xiàn)Winform中打開(kāi)網(wǎng)頁(yè)頁(yè)面的方法
- 01-10C#實(shí)現(xiàn)由四周向中心縮小的窗體退出特效
- 01-10Extjs4如何處理后臺(tái)json數(shù)據(jù)中日期和時(shí)間
- 01-10C#中DataGridView常用操作實(shí)例小結(jié)
- 01-10C#編程獲取資源文件中圖片的方法
- 01-10asp.net中XML如何做增刪改查操作
- 01-10C#利用反射技術(shù)實(shí)現(xiàn)去掉按鈕選中時(shí)的邊框效果
- 01-10C#中查找Dictionary中的重復(fù)值的方法
- 01-10C#中TreeView實(shí)現(xiàn)適合兩級(jí)節(jié)點(diǎn)的選中節(jié)點(diǎn)方法


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開(kāi)的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻 器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過(guò)重寫(xiě)Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10delphi制作wav文件的方法
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 04-02jquery與jsp,用jquery
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載