2010年9月16日 星期四

利用 ASP.Net 壓縮檔案

若要透過 ASP.Net 將 Web 站台的某些檔案進行壓縮,之後再讓使者下載,這需求透過 DotNetZip 來協助,問題就幾乎解決一大半,剩下的,就是如何讓產生的壓縮檔自動下載到使用者的電腦。

可以到 DotNetZip 下載最新 release 的版本。以目前所抓到的 v1.9版來說,解開之後,只要將 DotNetZip-v1.9\Release 裡的 Ionic.Zip.dll 加入到 Visual Studio 的參考就可完成 DotNetZip 的引用。重點是,這是免費的,作者甚至認為,有了他,就不用去買價值 29 美金的 winzip 了,作者也在網站上介紹他自己撰寫的程式,用以取代 winzip。

要將資料夾壓縮的語法,非常簡潔:

using Ionic.Zip;


using (ZipFile zip = new ZipFile())
{
    //將資料夾加入 zip
    zip.AddDirectory(MapPath(".\\SourceFiles"));

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

產生好壓縮檔後,如何讓這檔案下載到使用者電腦呢?當然,可以在網頁上放個超連結,給使用者點選,但如過進一步想更自動一點,則就是直接將附件檔自動下載。

這時,我在 .aspx 頁面放了一個 iframe ,並去設定這 iframe 的 src 屬性為下載連結。而我下載的連結則是透過 .ashx 來處理(可參考測試程式)。

<iframe id="ifies" runat="server" style="visibility:hidden"></iframe>
</form>

這裡我偷偷埋了一個 iframe,並將他的 visibility 設為隱藏,這樣使用者在網頁上就看不到他的存在了。最後,在產生壓縮檔程式裡頭加上 :

ifies.Attributes["src"] = string.Format("filedownload.ashx?filename={0}&path={1}", "MyZipFile.zip",MapPath(".\\"));

using Ionic.Zip;


using (ZipFile zip = new ZipFile())
{
    //將資料夾加入 zip
    zip.AddDirectory(MapPath(".\\SourceFiles"));

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

    //讓網頁執行下載動作
    ifies.Attributes["src"] = string.Format("filedownload.ashx?filename={0}&path={1}", "MyZipFile.zip",MapPath(".\\"));
    
}

最後可以觀察執行結果:

FireFox:直接跳出另存新檔


IE6:第一次會詢問安全性問題


Chrome:直接就幫你下載了


DotNetZip 除了能壓縮,也能解壓縮、支援 Dos 指令來操作,是程式開發人員不可或缺的好工具。

參考:http://dotnetzip.codeplex.com/
測試程式:下載

補充:20100929
最近使用 dotnetzip 時發生一個問題,就是中文檔名的文件,壓縮後都會變成亂碼。還好在一篇文章中有提到解法:

http://cheeso.members.winisp.net/DotNetZipHelp/html/aecbb638-1ecf-807e-b933-5bb1a2a95e81.htm

所以,要壓縮中文檔名時,記得程式要加上:

(承接上面的範例)
zip.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding("big5")

5 則留言:

  1. 您好~我使用您說的方式
    zip.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding("big5")

    中文還是會呈現(???) 請問您有成功的範例程式嗎?

    測試的檔案名稱: 這是中文名稱.txt

    回覆刪除
  2. .NET 4.0 測試程式
    https://sites.google.com/site/paladinsharefiles/home/filelist/zipTest.zip?attredirects=0&d=1

    我測試後,是正常的喔~

    using (ZipFile zip = new ZipFile())
    {
    //處理中文檔名問題
    zip.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding("big5");

    //將資料夾加入 zip
    zip.AddDirectory(MapPath(".\\SourceFiles"));

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

    }

    也請您再檢查一下,是否有疏忽的地方。

    回覆刪除
  3. 您好:
    我試出來了...用WinZip 解壓縮可以
    但適用WINRAR 就會來是(????)

    最後是找到用
    ZipFile zip = new ZipFile(System.Text.Encoding.Default))

    的方式處理...就解決了 ^^ 謝謝您的測試程式

    回覆刪除
  4. 感謝「牛」的建議喔。
    我使用您提到:System.Text.Encoding.Default 所壓出的檔案,在 WinZip 與 WinRAR 的確都可以正常解出。另外,我也使用 WinRAR 去解 原先使用System.Text.Encoding.GetEncoding("big5") 所壓的檔案,竟然也可以正常喔,不會如您所說的出現 ????,我猜想,會不會是 WinRAR 版本不同所致?我目前電腦上安裝的是 WinRAR 中文版 3.92。另外也很開心的從你那邊學到另一個不一樣的設定方式,謝謝你。

    回覆刪除
  5. = = 我查了一下 我也是用3.92 不過我的是中文試用版
    不知道會不會是試用版或是中文化的關係 ><?

    回覆刪除