亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > .NET > 正文

詳解最好的.NET開源免費ZIP庫DotNetZip(.NET組件介紹之三)

2024-07-10 13:31:46
字體:
來源:轉載
供稿:網友

在項目開發中,除了對數據的展示更多的就是對文件的相關操作,例如文件的創建和刪除,以及文件的壓縮和解壓。文件壓縮的好處有很多,主要就是在文件傳輸的方面,文件壓縮的好處就不需要贅述,因為無論是開發者,還是使用者對于文件壓縮的好處都是深有體會。至于文件壓縮的原理,在我的另一篇博客中有簡單的介紹,在這里就不再做介紹,需要了解的可以查看。

 .NET在System.IO.Compression命名空間中提供了GZip、Defalate兩種壓縮算法。今天我要介紹的一種壓縮組件是DotNetZip組件。

一.DotNetZip組件概述:

   在DotNetZip的自我介紹中號稱是”DotNetZip是.NET最好的開源ZIP庫“,至于是不是最好的壓縮組件,在這里就不做評價,畢竟每個使用者的心態和工作環境不同,項目對組件的需求也不同,在選擇組件的時候,就需要開發者自己衡量了。估計很多人還沒有看到這里就開始在鍵盤上敲字吐槽了,標題是我借用官方對外的宣傳口號,不用太在意這些細節。

   DotNetZip - Zip和解壓縮在C#,VB,任何.NET語言都可使用。DotNetZip是一個FAST,免費類庫和用于操縱zip文件的工具集。 使用VB,C?;蛉魏?NET語言輕松創建,解壓縮或更新zip文件。DotNetZip在具有完整.NET Framework的PC上運行,并且還在使用.NET Compact Framework的移動設備上運行。在VB,C#或任何.NET語言或任何腳本環境中創建和讀取zip文件。

  DotNetZip組件的使用環境,畢竟軟件的使用環境是每一個開發者都需要考慮的,這個世界沒有絕對的好事,當然也沒有絕對的壞事。接下來看一下其實用環境的說明吧:

1.一個動態創建zip文件的Silverlight應用程序。

2.一個ASP.NET應用程序,動態創建ZIP文件并允許瀏覽器下載它們。

3.一個Windows服務,定期地為了備份和歸檔目的上拉一個目錄。

4.修改現有歸檔的WPF程序 - 重命名條目,從歸檔中刪除條目或向歸檔中添加新條目。

5.一個Windows窗體應用程序,用于為歸檔內容的隱私創建AES加密的zip存檔。

6.解壓縮或拉鏈的SSIS腳本。

7.PowerShell或VBScript中的一個管理腳本,用于執行備份和歸檔。

8.WCF服務,接收作為附件的zip文件,并動態地將zip解壓縮到流以進行分析。

9.一個老式的ASP(VBScript)應用程序,通過COM接口為DotNetZIp生成一個ZIP文件。

10.讀取或更新ODS文件的Windows Forms應用程序。

11.從流內容創建zip文件,保存到流,提取到流,從流讀取。

12.創建自解壓檔案。

DotNetZip是一個100%的托管代碼庫,可用于任何.NET應用程序 - 控制臺,Winforms,WPF,ASP.NET,Sharepoint,Web服務應用程序等。 新的v1.9.1.6:Silverlight。 它還可以從腳本環境或具有COM功能的環境(如Powershell腳本,VBScript,VBA,VB6,PHP,Perl,Javascript等)中使用。 無論使用什么環境,DotNetZip生成的zip文件可與Windows資源管理器以及Java應用程序,在Linux上運行的應用程序完全互操作。

該組件設計簡單,易于使用。 DotNetZip打包為一個單一的DLL,大小約400k。 它沒有第三方依賴。 它是中等信任,因此可以在大多數托管商使用。 通過引用DLL來獲取壓縮。 該庫支持zip密碼,Unicode,ZIP64,流輸入和輸出,AES加密,多個壓縮級別,自解壓縮存檔,跨區存檔等。

 以上的一些描述來自與官網,就不再吹捧這個組件了,在這里需要說明的是在組件的選擇和使用上,主要取決與項目的實際情況。詳情見:http://dotnetzip.codeplex.com/

二.DotNetZip相關核心類和方法解析:

由于下載的是DLL文件,還是采用.NET Reflector對DLL文件進行反編譯,以此查看源代碼。一下主要介紹一些類和方法,沒有完全介紹,首先是由于篇幅所限,其實是完全沒有必要,因為對于開發者而言,沒有必要全部了解這些類,在實際的開發中,可以根據API進行對應的方法調用,這些技能應該是一個開發人員應該具備的。

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()讀取數據流:

 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文件后,可以直接查看相應的方法和屬性,在這里就不做詳細的介紹。

三.DotNetZip組件使用實例:

以上是對該組件的一些解析,接下來我們看看實例:

1.壓縮ZIP文件:

/// <summary>  /// 壓縮ZIP文件  /// 支持多文件和多目錄,或是多文件和多目錄一起壓縮  /// </summary>  /// <param name="list">待壓縮的文件或目錄集合</param>  /// <param name="strZipName">壓縮后的文件名</param>  /// <param name="isDirStruct">是否按目錄結構壓縮</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   {    //設置編碼,解決壓縮文件時中文亂碼    using (var zip = new ZipFile(Encoding.Default))    {     foreach (var path in list)     {      //取目錄名稱      var fileName = Path.GetFileName(path);      //如果是目錄      if (Directory.Exists(path))      {       //按目錄結構壓縮       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    };    //設置編碼,解決解壓文件時中文亂碼    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">源數據流</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.得到指定的字節數組的ZIP解壓流對象:

/// <summary>  /// 得到指定的字節數組的ZIP解壓流對象  /// 當前方法僅適用于只有一個壓縮文件的壓縮包,即方法內只取壓縮包中的第一個壓縮文件  /// </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,后續使用時必須先將Stream位置歸零,否則會導致后續讀取不到任何數據      // 返回該Stream對象之前進行一次位置歸零動作      decompressedStream.Position = 0;     }    }   }   catch(Exception ex)   {    throw new Exception(ex.Message);   }   return decompressedStream;  }

四.總結:

 以上是對DotNetZip組件的一些解析和方法實例,至于這款組件是不是最好的.NET壓縮組件,這個就不做評價。個人在選擇組件的時候,首先考慮的是開源,其次是免費,最后再考慮效率和實用性,畢竟在國內的一些情況是所有開發者都清楚的(不提國外是由于我不知道國外的情況)??蛻粜枰档统杀荆⑶医M件要可以進行定制。不過個人認為收費應該是一種趨勢,畢竟所有的產品都是需要人員進行維護和開發。以上的博文中有不足之處,還望多多指正。


注:相關教程知識閱讀請移步到ASP.NET教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
26uuu另类亚洲欧美日本一| 91av国产在线| 中日韩午夜理伦电影免费| 欧美午夜片欧美片在线观看| 久久久久久久久久国产精品| 久久久精品美女| 深夜福利日韩在线看| 国产日韩欧美一二三区| 日韩美女在线观看| 欧美亚洲伦理www| 欧美成人免费网| 国产精品美女无圣光视频| 自拍视频国产精品| 欧美高清激情视频| 成人欧美一区二区三区黑人| 日韩高清av一区二区三区| 久久精品中文字幕| 国产日本欧美一区二区三区在线| 精品一区二区三区四区| 成人av资源在线播放| 国产伦精品一区二区三区精品视频| 九九久久久久久久久激情| 国产精品视频久久久| 日韩精品视频在线免费观看| 亚洲最新av在线| 黄色成人av在线| 夜夜躁日日躁狠狠久久88av| 国产精品欧美一区二区三区奶水| 久久99热精品这里久久精品| 亚洲色图17p| 欧美成年人网站| 精品国产美女在线| 国产午夜一区二区| 亚洲国产欧美一区二区三区久久| 久久精品国产亚洲精品| 亚洲精美色品网站| 国产精品老牛影院在线观看| 在线丨暗呦小u女国产精品| 亚洲第一男人天堂| 一区二区欧美久久| 欧美成人黄色小视频| 国产精品欧美激情| 日韩人体视频一二区| 26uuu亚洲伊人春色| 久久乐国产精品| 国产日韩亚洲欧美| 日韩成人av在线播放| 色中色综合影院手机版在线观看| 国产成人精品一区二区| 久久综合国产精品台湾中文娱乐网| 亚洲片国产一区一级在线观看| 91精品免费看| 久久亚洲国产成人| 国产一区二区三区免费视频| 日韩精品中文字| 九九精品视频在线| 北条麻妃一区二区在线观看| 久久久久久久999精品视频| 久久成人免费视频| 久久视频免费在线播放| 国产69久久精品成人| 57pao精品| 久久香蕉国产线看观看av| 国产精品日韩欧美综合| 国产午夜精品麻豆| 国模精品一区二区三区色天香| 成人黄色激情网| 国产成人精品999| 日韩极品精品视频免费观看| 国产精品久久久久久久7电影| 欧美色视频日本版| 97免费视频在线播放| 国产精品一区二区久久久久| 国产999在线观看| 久久免费国产精品1| 色播久久人人爽人人爽人人片视av| 亚洲成成品网站| 成人黄色av免费在线观看| 日韩欧美国产视频| 久久视频国产精品免费视频在线| 一本色道久久88亚洲综合88| 91av在线不卡| 8090理伦午夜在线电影| 久久99亚洲热视| 欧美激情第三页| 欧美又大粗又爽又黄大片视频| 97久久精品人人澡人人爽缅北| 91性高湖久久久久久久久_久久99| 欧美日韩人人澡狠狠躁视频| 亚洲人成绝费网站色www| 亚洲人成网站999久久久综合| 亚洲精品美女久久久| 色婷婷久久av| xxxxx成人.com| 国产精品伦子伦免费视频| 欧美激情一区二区三级高清视频| 欧美日韩加勒比精品一区| 最好看的2019年中文视频| 91欧美日韩一区| xxxxx成人.com| 国产精品久久激情| 国产精品男女猛烈高潮激情| 国产亚洲精品高潮| 亚洲成人av资源网| 精品中文字幕在线观看| 久久影视电视剧免费网站清宫辞电视| 国产精品久久久久久久天堂| 国产精品video| 美女少妇精品视频| 亚洲国产欧美一区二区丝袜黑人| 狠狠躁夜夜躁久久躁别揉| 久久久999国产| 精品久久久久久久中文字幕| 91久久嫩草影院一区二区| 亚洲欧美中文字幕在线一区| 中文字幕久热精品视频在线| 成人写真视频福利网| 26uuu另类亚洲欧美日本老年| 欧美日韩福利在线观看| 国产成人一区二区三区电影| 九九热这里只有精品6| 欧洲美女7788成人免费视频| 怡红院精品视频| 91免费在线视频| 日韩av最新在线| 精品国产一区二区三区久久| 欧美精品免费播放| 欧美电影电视剧在线观看| 亚洲精品v天堂中文字幕| 91av在线国产| 中文亚洲视频在线| 一区二区在线免费视频| 欧美激情aaaa| 日韩成人中文字幕在线观看| 亚洲成人黄色在线观看| 91久久久久久久久久久| 国产精品视频xxxx| www.欧美三级电影.com| 欧美一级电影免费在线观看| 欧美日韩亚洲一区二区三区| 亚洲新声在线观看| 日韩在线视频网站| 亚洲片国产一区一级在线观看| 久久久久久久国产精品| 亚洲黄一区二区| 国产亚洲欧美aaaa| 成人夜晚看av| 久久精品电影一区二区| 久久资源免费视频| 日韩av一区二区在线| 久久久久久久国产精品视频| 欧美亚洲在线播放| 中文字幕日韩欧美在线| 国产精自产拍久久久久久| 奇门遁甲1982国语版免费观看高清| 91久久国产综合久久91精品网站| 欧美一级电影久久| 992tv成人免费视频| 亚洲视频axxx| 4k岛国日韩精品**专区| 欧美在线一级视频| 久久免费成人精品视频| 日韩高清电影好看的电视剧电影| 亚洲精品久久久久国产|