如何使用.NET開源免費ZIP庫DotNetZip,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
永清ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!在項目開發(fā)中,除了對數(shù)據(jù)的展示更多的就是對文件的相關(guān)操作,例如文件的創(chuàng)建和刪除,以及文件的壓縮和解壓。文件壓縮的好處有很多,主要就是在文件傳輸?shù)姆矫?,文件壓縮的好處就不需要贅述,因為無論是開發(fā)者,還是使用者對于文件壓縮的好處都是深有體會。
.NET在System.IO.Compression命名空間中提供了GZip、Defalate兩種壓縮算法。今天我要介紹的一種壓縮組件是DotNetZip組件。
一.DotNetZip組件概述:
在DotNetZip的自我介紹中號稱是”DotNetZip是.NET好的開源ZIP庫“,至于是不是好的壓縮組件,在這里就不做評價,畢竟每個使用者的心態(tài)和工作環(huán)境不同,項目對組件的需求也不同,在選擇組件的時候,就需要開發(fā)者自己衡量了。估計很多人還沒有看到這里就開始在鍵盤上敲字吐槽了,標(biāo)題是我借用官方對外的宣傳口號,不用太在意這些細(xì)節(jié)。
DotNetZip - Zip和解壓縮在C#,VB,任何.NET語言都可使用。DotNetZip是一個FAST,免費類庫和用于操縱zip文件的工具集。 使用VB,C?;蛉魏?NET語言輕松創(chuàng)建,解壓縮或更新zip文件。DotNetZip在具有完整.NET Framework的PC上運行,并且還在使用.NET Compact Framework的移動設(shè)備上運行。在VB,C#或任何.NET語言或任何腳本環(huán)境中創(chuàng)建和讀取zip文件。
DotNetZip組件的使用環(huán)境,畢竟軟件的使用環(huán)境是每一個開發(fā)者都需要考慮的,這個世界沒有絕對的好事,當(dāng)然也沒有絕對的壞事。接下來看一下其實用環(huán)境的說明吧:
1.一個動態(tài)創(chuàng)建zip文件的Silverlight應(yīng)用程序。
2.一個ASP.NET應(yīng)用程序,動態(tài)創(chuàng)建ZIP文件并允許瀏覽器下載它們。
3.一個Windows服務(wù),定期地為了備份和歸檔目的上拉一個目錄。
4.修改現(xiàn)有歸檔的WPF程序 - 重命名條目,從歸檔中刪除條目或向歸檔中添加新條目。
5.一個Windows窗體應(yīng)用程序,用于為歸檔內(nèi)容的隱私創(chuàng)建AES加密的zip存檔。
6.解壓縮或拉鏈的SSIS腳本。
7.PowerShell或VBScript中的一個管理腳本,用于執(zhí)行備份和歸檔。
8.WCF服務(wù),接收作為附件的zip文件,并動態(tài)地將zip解壓縮到流以進(jìn)行分析。
9.一個老式的ASP(VBScript)應(yīng)用程序,通過COM接口為DotNetZIp生成一個ZIP文件。
10.讀取或更新ODS文件的Windows Forms應(yīng)用程序。
11.從流內(nèi)容創(chuàng)建zip文件,保存到流,提取到流,從流讀取。
12.創(chuàng)建自解壓檔案。
DotNetZip是一個100%的托管代碼庫,可用于任何.NET應(yīng)用程序 - 控制臺,Winforms,WPF,ASP.NET,Sharepoint,Web服務(wù)應(yīng)用程序等。 新的v1.9.1.6:Silverlight。 它還可以從腳本環(huán)境或具有COM功能的環(huán)境(如Powershell腳本,VBScript,VBA,VB6,PHP,Perl,Javascript等)中使用。 無論使用什么環(huán)境,DotNetZip生成的zip文件可與Windows資源管理器以及Java應(yīng)用程序,在Linux上運行的應(yīng)用程序完全互操作。
該組件設(shè)計簡單,易于使用。 DotNetZip打包為一個單一的DLL,大小約400k。 它沒有第三方依賴。 它是中等信任,因此可以在大多數(shù)托管商使用。 通過引用DLL來獲取壓縮。 該庫支持zip密碼,Unicode,ZIP64,流輸入和輸出,AES加密,多個壓縮級別,自解壓縮存檔,跨區(qū)存檔等。
以上的一些描述來自與官網(wǎng),就不再吹捧這個組件了,在這里需要說明的是在組件的選擇和使用上,主要取決與項目的實際情況。詳情見:http://dotnetzip.codeplex.com/
二.DotNetZip相關(guān)核心類和方法解析:
由于下載的是DLL文件,還是采用.NET Reflector對DLL文件進(jìn)行反編譯,以此查看源代碼。一下主要介紹一些類和方法,沒有完全介紹,首先是由于篇幅所限,其實是完全沒有必要,因為對于開發(fā)者而言,沒有必要全部了解這些類,在實際的開發(fā)中,可以根據(jù)API進(jìn)行對應(yīng)的方法調(diào)用,這些技能應(yīng)該是一個開發(fā)人員應(yīng)該具備的。
1.ZipFile類的AddEntry()、Save()和IsZipFile()方法:
public ZipEntry AddEntry(string entryName, WriteDelegate writer) { ZipEntry ze = ZipEntry.CreateForWriter(entryName, writer); if (this.Verbose) { this.StatusMessageTextWriter.WriteLine("adding {0}...", entryName); } return this._InternalAddEntry(ze); }
public void Save() { try { bool flag = false; this._saveOperationCanceled = false; this._numberOfSegmentsForMostRecentSave = 0; this.OnSaveStarted(); if (this.WriteStream == null) { throw new BadStateException("You haven't specified where to save the zip."); } if (((this._name != null) && this._name.EndsWith(".exe")) && !this._SavingSfx) { throw new BadStateException("You specified an EXE for a plain zip file."); } if (!this._contentsChanged) { this.OnSaveCompleted(); if (this.Verbose) { this.StatusMessageTextWriter.WriteLine("No save is necessary...."); } } else { this.Reset(true); if (this.Verbose) { this.StatusMessageTextWriter.WriteLine("saving...."); } if ((this._entries.Count >= 0xffff) && (this._zip64 == Zip64Option.Default)) { throw new ZipException("The number of entries is 65535 or greater. Consider setting the UseZip64WhenSaving property on the ZipFile instance."); } int current = 0; ICollection<ZipEntry> entries = this.SortEntriesBeforeSaving ? this.EntriesSorted : this.Entries; foreach (ZipEntry entry in entries) { this.OnSaveEntry(current, entry, true); entry.Write(this.WriteStream); if (this._saveOperationCanceled) { break; } current++; this.OnSaveEntry(current, entry, false); if (this._saveOperationCanceled) { break; } if (entry.IncludedInMostRecentSave) { flag |= entry.OutputUsedZip64.Value; } } if (!this._saveOperationCanceled) { ZipSegmentedStream writeStream = this.WriteStream as ZipSegmentedStream; this._numberOfSegmentsForMostRecentSave = (writeStream != null) ? writeStream.CurrentSegment : 1; bool flag2 = ZipOutput.WriteCentralDirectoryStructure(this.WriteStream, entries, this._numberOfSegmentsForMostRecentSave, this._zip64, this.Comment, new ZipContainer(this)); this.OnSaveEvent(ZipProgressEventType.Saving_AfterSaveTempArchive); this._hasBeenSaved = true; this._contentsChanged = false; flag |= flag2; this._OutputUsesZip64 = new bool?(flag); if ((this._name != null) && ((this._temporaryFileName != null) || (writeStream != null))) { this.WriteStream.Dispose(); if (this._saveOperationCanceled) { return; } if (this._fileAlreadyExists && (this._readstream != null)) { this._readstream.Close(); this._readstream = null; foreach (ZipEntry entry2 in entries) { ZipSegmentedStream stream2 = entry2._archiveStream as ZipSegmentedStream; if (stream2 != null) { stream2.Dispose(); } entry2._archiveStream = null; } } string path = null; if (File.Exists(this._name)) { path = this._name + "." + Path.GetRandomFileName(); if (File.Exists(path)) { this.DeleteFileWithRetry(path); } File.Move(this._name, path); } this.OnSaveEvent(ZipProgressEventType.Saving_BeforeRenameTempArchive); File.Move((writeStream != null) ? writeStream.CurrentTempName : this._temporaryFileName, this._name); this.OnSaveEvent(ZipProgressEventType.Saving_AfterRenameTempArchive); if (path != null) { try { if (File.Exists(path)) { File.Delete(path); } } catch { } } this._fileAlreadyExists = true; } NotifyEntriesSaveComplete(entries); this.OnSaveCompleted(); this._JustSaved = true; } } } finally { this.CleanupAfterSaveOperation(); } }
public static bool IsZipFile(Stream stream, bool testExtract) { if (stream == null) { throw new ArgumentNullException("stream"); } bool flag = false; try { if (!stream.CanRead) { return false; } Stream @null = Stream.Null; using (ZipFile file = Read(stream, null, null, null)) { if (testExtract) { foreach (ZipEntry entry in file) { if (!entry.IsDirectory) { entry.Extract(@null); } } } } flag = true; } catch (IOException) { } catch (ZipException) { } return flag; }
2.Read()讀取數(shù)據(jù)流:
private static ZipFile Read(Stream zipStream, TextWriter statusMessageWriter, Encoding encoding, EventHandler<ReadProgressEventArgs> readProgress) { if (zipStream == null) { throw new ArgumentNullException("zipStream"); } ZipFile zf = new ZipFile { _StatusMessageTextWriter = statusMessageWriter, _alternateEncoding = encoding ?? DefaultEncoding, _alternateEncodingUsage = ZipOption.Always }; if (readProgress != null) { zf.ReadProgress += readProgress; } zf._readstream = (zipStream.Position == 0L) ? zipStream : new OffsetStream(zipStream); zf._ReadStreamIsOurs = false; if (zf.Verbose) { zf._StatusMessageTextWriter.WriteLine("reading from stream..."); } ReadIntoInstance(zf); return zf; }
以上是對ZipFile類的一些方法的解析,提供了該組件的一些方法的源碼,至于源碼的解讀上難度不是很大,至于該組件的API,可以在下載DLL文件后,可以直接查看相應(yīng)的方法和屬性,在這里就不做詳細(xì)的介紹。
三.DotNetZip組件使用實例:
以上是對該組件的一些解析,接下來我們看看實例:
1.壓縮ZIP文件:
/// <summary> /// 壓縮ZIP文件 /// 支持多文件和多目錄,或是多文件和多目錄一起壓縮 /// </summary> /// <param name="list">待壓縮的文件或目錄集合</param> /// <param name="strZipName">壓縮后的文件名</param> /// <param name="isDirStruct">是否按目錄結(jié)構(gòu)壓縮</param> /// <returns>成功:true/失?。篺alse</returns> public static bool CompressMulti(List<string> list, string strZipName, bool isDirStruct) { if (list == null) { throw new ArgumentNullException("list"); } if (string.IsNullOrEmpty(strZipName)) { throw new ArgumentNullException(strZipName); } try { //設(shè)置編碼,解決壓縮文件時中文亂碼 using (var zip = new ZipFile(Encoding.Default)) { foreach (var path in list) { //取目錄名稱 var fileName = Path.GetFileName(path); //如果是目錄 if (Directory.Exists(path)) { //按目錄結(jié)構(gòu)壓縮 if (isDirStruct) { zip.AddDirectory(path, fileName); } else { //目錄下的文件都壓縮到Zip的根目錄 zip.AddDirectory(path); } } if (File.Exists(path)) { zip.AddFile(path); } } //壓縮 zip.Save(strZipName); return true; } } catch (Exception ex) { throw new Exception(ex.Message); } }
2.解壓ZIP文件:
/// <summary> /// 解壓ZIP文件 /// </summary> /// <param name="strZipPath">待解壓的ZIP文件</param> /// <param name="strUnZipPath">解壓的目錄</param> /// <param name="overWrite">是否覆蓋</param> /// <returns>成功:true/失?。篺alse</returns> public static bool Decompression(string strZipPath, string strUnZipPath, bool overWrite) { if (string.IsNullOrEmpty(strZipPath)) { throw new ArgumentNullException(strZipPath); } if (string.IsNullOrEmpty(strUnZipPath)) { throw new ArgumentNullException(strUnZipPath); } try { var options = new ReadOptions { Encoding = Encoding.Default }; //設(shè)置編碼,解決解壓文件時中文亂碼 using (var zip = ZipFile.Read(strZipPath, options)) { foreach (var entry in zip) { if (string.IsNullOrEmpty(strUnZipPath)) { strUnZipPath = strZipPath.Split('.').First(); } entry.Extract(strUnZipPath,overWrite ? ExtractExistingFileAction.OverwriteSilently : ExtractExistingFileAction.DoNotOverwrite); } return true; } } catch (Exception ex) { throw new Exception(ex.Message); } }
3.得到指定的輸入流的ZIP壓縮流對象:
/// <summary> /// 得到指定的輸入流的ZIP壓縮流對象 /// </summary> /// <param name="sourceStream">源數(shù)據(jù)流</param> /// <param name="entryName">實體名稱</param> /// <returns></returns> public static Stream ZipCompress(Stream sourceStream, string entryName = "zip") { if (sourceStream == null) { throw new ArgumentNullException("sourceStream"); } var compressedStream = new MemoryStream(); long sourceOldPosition = 0; try { sourceOldPosition = sourceStream.Position; sourceStream.Position = 0; using (var zip = new ZipFile()) { zip.AddEntry(entryName, sourceStream); zip.Save(compressedStream); compressedStream.Position = 0; } } catch (Exception ex) { throw new Exception(ex.Message); } finally { try { sourceStream.Position = sourceOldPosition; } catch (Exception ex) { throw new Exception(ex.Message); } } return compressedStream; }
4.得到指定的字節(jié)數(shù)組的ZIP解壓流對象:
/// <summary> /// 得到指定的字節(jié)數(shù)組的ZIP解壓流對象 /// 當(dāng)前方法僅適用于只有一個壓縮文件的壓縮包,即方法內(nèi)只取壓縮包中的第一個壓縮文件 /// </summary> /// <param name="data"></param> /// <returns></returns> public static Stream ZipDecompress(byte[] data) { Stream decompressedStream = new MemoryStream(); if (data == null) return decompressedStream; try { var dataStream = new MemoryStream(data); using (var zip = ZipFile.Read(dataStream)) { if (zip.Entries.Count > 0) { zip.Entries.First().Extract(decompressedStream); // Extract方法中會操作ms,后續(xù)使用時必須先將Stream位置歸零,否則會導(dǎo)致后續(xù)讀取不到任何數(shù)據(jù) // 返回該Stream對象之前進(jìn)行一次位置歸零動作 decompressedStream.Position = 0; } } } catch(Exception ex) { throw new Exception(ex.Message); } return decompressedStream; }
看完上述內(nèi)容,你們掌握如何使用.NET開源免費ZIP庫DotNetZip的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!
分享標(biāo)題:如何使用.NET開源免費ZIP庫DotNetZip-創(chuàng)新互聯(lián)
地址分享:http://aaarwkj.com/article14/cchpge.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、品牌網(wǎng)站建設(shè)、網(wǎng)站營銷、全網(wǎng)營銷推廣、定制開發(fā)、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容