關於我

我的相片
用心思考、保持熱情,把工作上的經驗作分享與紀錄。希望能夠跟大家一起不斷的成長~

Streaming a zip file over http in .net with SharpZipLib

今天因為專案需求,需要於網站上可以將多個檔案zip後,Popup下載視窗,讓User可下載檔案zip包。這個需求之前有做過的做法如下:
  1. 先將所有要zip的檔案zip至一個暫存的目錄中。
  2. 將zip檔讀入為byte[],再Response.binarywrite出該byte[]檔案。
  3. 再將暫存檔案刪除。

可是這樣的做法,多了一個暫存的動作。

實在不是個好的做法。

因此今天花了點時間,找到了一個參考Sample

以此Sample即可達成省去暫存zip檔的步驟。

  1. 將要壓縮的檔案,一個一個讀入,zip後放入Stream中。
  2. 直接將Stream於網頁output出來即可。

以下為實際完成的程式。

using System;
using System.Text;
using System.Web;
using System.Xml;
using System.Data;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Core;
using System.IO;
using System.Collections.Generic;
namespace VAT2005.Forms
{
  class Utility
  {
    /// <summary>
    /// 將多個檔案zip後,Response下載!
    /// </summary>
    /// <param name="context">HttpContext</param>
    /// <param name="fileNames">要zip的多個檔案完整路徑與檔名</param>
    /// <param name="outputfilename">要output之zip檔案檔名</param>
    public static void DownloadFilesZip(HttpContext context, List<string> fileNames, string outputfilename)
    {
      context.Response.ContentType = "application/x-zip-compressed";
      context.Response.AppendHeader("content-disposition", string.Format("attachment; filename={0}", outputfilename));
      context.Response.ContentEncoding = Encoding.Default;
      context.Response.Charset = "";
      //設定zip時,buffer的大小
      byte[] buffer = new byte[1024 * 8];
      using (ZipOutputStream zipOutput = new ZipOutputStream(context.Response.OutputStream))
      {
        //依序讀入要zip的檔案
        foreach (string fileName in fileNames)
        {
          //新增zip檔案
          ZipEntry zipEntry = new ZipEntry(fileName.Substring(fileName.LastIndexOf('\\') + 1));
          //放入OutputStream中
          zipOutput.PutNextEntry(zipEntry);
          //讀入file
          using (FileStream fread = File.OpenRead(fileName))
          {
            //將file(Stream)使用buffer zip後,放入zipOutput中
            StreamUtils.Copy(fread, zipOutput, buffer);
          }
        }
        zipOutput.Finish();
      }
      context.Response.Flush();
      //完成Stream寫出,讓User下載
      context.Response.End();
    }
  }
}
透過上方做法,即可直接將要zip的多個檔案,zip後,讓User下載!

當然,此zip做法是使用SharpZipLib,必須要referance才可使用!

沒有留言:

張貼留言