介紹幾款好用的壓縮函示庫:SharpZipLib 與 DotNetZip

  分享到噗浪!

在專案中或多或少都有機會遇到需要處理壓縮檔的情況,而一般最常見的壓縮格式就是 ZIP 格式,雖然有人愛用 RAR 格式,但因為若要建立 RAR 壓縮檔時,只能用 WinRAR 軟體,而這是個需付費的商業軟體,所以我本身很不愛用,大多僅使用 ZIP7-Zip 等較為開放的壓縮格式。

今天我就來介紹兩款我曾經用過的壓縮函示庫:

1. SharpZipLib - .NET Zip Library

SharpZipLib 是完全用 C# 撰寫並附有完整原始碼可供下載,此元件也已經問世一段時間了,我幾年前就用過了,支援多種壓縮格式,包括 Zip, GZip, BZip2 and Tar 等。

至於使用此元件的方式是採用 Stream 的方式開發,跟 .NET BCL 內建的 GZipStream 用法差不多,差別在於 ZIP 格式可以壓縮「多個檔案」而已,若已經有使用過 GZipStream 的人要上手也不是什麼難事。

以下是我從下載的範例程式中擷取的程式碼片段,這段是用來建立一個 Zip 檔的範例:

string[] filenames = Directory.GetFiles(args[0]);
using (ZipOutputStream s = new ZipOutputStream(File.Create(args[1])))
{
    s.SetLevel(9); // 0 - store only to 9 - means best compression
    byte[] buffer = new byte[4096];
    foreach (string file in filenames)
    {
        ZipEntry entry = new ZipEntry(Path.GetFileName(file));
        entry.DateTime = DateTime.Now;
        s.PutNextEntry(entry);        
        using ( FileStream fs = File.OpenRead(file) ) {
            int sourceBytes;
            do {
                sourceBytes = fs.Read(buffer, 0, buffer.Length);
                s.Write(buffer, 0, sourceBytes);
            } while ( sourceBytes > 0 );
        }
    }    
    s.Finish();
    s.Close();
}

2. DotNetZip - anage ZIP files from within .NET applications

如果你單純的只想使用 Zip 壓縮、解壓縮的話,我個人是建議使用 DotNetZip 即可,光看範例程式就知道他的精簡與直覺的使用方法:

壓縮檔案

using (ZipFile zip = new ZipFile("Archive.zip"))
{
    zip.AddFile("ReadMe.txt");
    zip.AddFile("7440-N49th.png");
    zip.AddFile("2005_Annual_Report.pdf");        
    zip.Save();
}

壓縮檔案 ( 含密碼保護 )

using (ZipFile zip = new ZipFile("Backup.zip"))
{
  zip.Password= "123456!";
  zip.AddFile("ReadMe.txt");
  zip.AddFile("7440-N49th.png");
  zip.AddFile("2005_Annual_Report.pdf");        
  zip.Save();
}

壓縮檔案 ( 可根據不同檔案設定不同的解壓縮密碼 )

using (ZipFile zip = new ZipFile("Backup.zip"))
{
  zip.AddFile("ReadMe.txt"); // no password for this entry

  zip.Password= "123456!";
  ZipEntry e = zip.AddFile("7440-N49th.png");
  e.Comment = "Map of the company headquarters."; 

  zip.Password= "!Secret1";
  zip.AddFile("2Q2008_Operations_Report.pdf");
  
  zip.Save();
}

壓縮整個目錄 ( 還可對壓縮的項目設定註解 )

using (ZipFile zip = new ZipFile(ZipFileToCreate))
{
  zip.AddDirectory(@"MyDocuments\ProjectX");
  zip.Comment = "This zip was created at " + System.DateTime.Now.ToString("G") ; 
  zip.Save();
}

在 ASP.NET 頁面中實做下載壓縮檔功能 ( 直接將壓縮檔輸出到 Response.OutputStream 喔 )

public void btnGo_Click (Object sender, EventArgs e)
{
  Response.Clear();
  String ReadmeText= "This is a zip file dynamically generated at " 
    + System.DateTime.Now.ToString("G");
  string filename = System.IO.Path.GetFileName(ListOfFiles.SelectedItem.Text) + ".zip";
  Response.ContentType = "application/zip";
  Response.AddHeader("content-disposition", "filename=" + filename);
  
  using (ZipFile zip = new ZipFile(Response.OutputStream)) {
    zip.AddFile(ListOfFiles.SelectedItem.Text, "files");
    zip.AddFileFromString("Readme.txt", "", ReadmeText);
    zip.Save();
  }
 
  Response.End();
}

還有一堆範例程式可以在這裡看到。不過光看到以上的範例就知道好用了吧! ^_^

---

最後,還有一個鮮為人知的壓縮、解壓縮的類別庫潛藏在 Visual J# Class Library 中,說也奇怪,這麼常用的功能盡然潛藏在一個這麼少人用的地方,若有興趣瞭解的人可以參考以下文章:

相關連結

此文章由 will 發表於 2009/1/11 下午 10:43:34

永久連結 | 評論 (15) | 此文章的RSSRSS comment feed |

分類: .Net | C# | ASP.NET

標籤: , , ,

評論

一月 12. 2009 09:57

tomexou

我也推薦dotnetzip,它也持續在更新
很棒的library。

tomexou Taiwan

三月 11. 2009 23:39

uuuiii00

請問
我公司開發的軟體還是用Framework.net 1.1
好像沒辦法加入DotNetZip函示庫
是不是要用註冊的方式
才可使用這個函示庫呢?
那該如何加入註冊呢??

uuuiii00 Taiwan

三月 12. 2009 09:31

will

至少要 .NET 2.0 以上才能用

will Taiwan

六月 24. 2009 07:56

評論

四五年前我用 J# Class Library 來壓縮檔案 很好用
但是檔案的日期全部變成零
股溝一下那是 Microsoft 的 Bug

評論 United States

八月 7. 2010 00:07

ggtt

如何在使用sharpziplib時,不要把檔案路徑一起加入進去

ggtt Taiwan

八月 7. 2010 12:39

Will 保哥

ggtt: 你多看些範例,多試幾次就可以試出來了,我手邊沒有現成的範例可給你。

Will 保哥 Taiwan

九月 25. 2010 20:16

CCH

請問我用DotNetZip壓縮時遇到中文的檔名會出問題(?號),不知您有否解決辦法?謝謝!

CCH Taiwan

九月 26. 2010 02:49

Will 保哥

CCH: 因為 DotNetZip 預設使用 IBM437 編碼(Encoding),所以壓縮中文時會變問號,你只要自行指定適當的編碼(如UTF8)即可解決此問題,如下程式碼範例:

using (ZipFile zip = new ZipFile())
{
    zip.ProvisionalAlternateEncoding = Encoding.UTF8;

    // ...

    zip.Save(ZipFileToCreate);
}

Will 保哥 Taiwan

一月 3. 2011 13:48

trackback

DotNetZip

DotNetZip

Level Up

二月 8. 2011 23:50

聽.風

之前寫一個備份程式時就有壓縮的需求XD

聽.風 Taiwan

四月 19. 2011 14:30

牛

您好
DotNetZip壓縮時遇到中文的檔名會出問題,我使用您說的方式無效耶

以及利用他說明文件的方式(cheeso.members.winisp.net/.../...5bb1a2a95e81.htm)
zip.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding("big5");
也無效
請問有可能是哪裡還要設定嗎?
程式碼:
using (ZipFile zip = new ZipFile())
        {
            //將資料夾加入 zip
            zip.AddDirectory(MapPath(".\\SourceFiles"));

            //zip.ProvisionalAlternateEncoding = Encoding.UTF8;
            zip.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding("big5");

            //產生 zip 檔
            zip.Save(MapPath(".\\")+"MyZipFile.zip");

            //讓網頁執行下載動作
            ifies.Attributes["src"] = string.Format("filedownload.ashx?filename={0}&path={1}", "MyZipFile.zip",MapPath(".\\"));
        }
檔案名:這是中文名稱.txt

PS: 我是用RAR 軟體開檔

Taiwan

四月 20. 2011 08:43

牛

嗯~找出問題了...似乎是WINRAR 的問題...用WINZIP 就可以正常開啟

Taiwan

四月 21. 2011 20:51

张良

支持中文那个回复太好了,解决了我的大问题,感谢

张良 People's Republic of China

四月 28. 2011 23:33

安焯

那請問,我遇到解壓文檔時,中文出現亂碼應該如何解決? 期待你的答復!

安焯 People's Republic of China

三月 7. 2012 17:11

ming

您好,

若需要壓縮的檔案名稱可能有多種的語系時,
是否有方式可以處理(繁體, 簡中, 日文…等)?!

目前試了同時有繁體及簡體的兩個檔案時, 只有繁體會被包在zip中!

如果有方式可以處理, 或解法請您告知一下,Thanks!

ming

ming Taiwan

新增評論


( 您輸入的Email不會顯示於網站上 )

  Country flag

biuquote
  • 評論
  • 線上預覽
Loading