Create a Zip as a browser download attachment in IIS - icsharpcode/SharpZipLib GitHub Wiki
Code Reference / Zip Samples / Create a Zip as a browser download attachment in IIS
This sample creates a zip as a browser download.
By writing directly to the Response OutputStream, zip download starts immediately, which fixes timeout problems when zipping large files.
For inputting from a memorystream instead of disk files, or passwording etc, see the samples above.
// the aspx page has just one line e.g. <%@ Page language="c#" Codebehind=...
// but if you must run this from within a page that has other output, start
// with a Response.Clear();
using ICSharpCode.SharpZipLib.Zip;
// This will accumulate each of the files named in the fileList into a zip file,
// and stream it to the browser.
// This approach writes directly to the Response OutputStream.
// The browser starts to receive data immediately which should avoid
// timeout problems.
// This also avoids an intermediate memorystream, saving memory on large files.
private void DownloadZipToBrowser(List <string> zipFileList) {
Response.ContentType = "application/zip";
// If the browser is receiving a mangled zipfile, IIS Compression may cause
// this problem. Some members have found that
//Response.ContentType = "application/octet-stream"
// has solved this. May be specific to Internet Explorer.
Response.AppendHeader("Content-Disposition",
"attachment; filename=\"Download.zip\"");
Response.CacheControl = "Private";
Response.Cache.SetExpires(DateTime.Now.AddMinutes(3));
// or put a timestamp in the filename in the content-disposition
var buffer = new byte[4096];
using(var zipOutputStream = new ZipOutputStream(Response.OutputStream)){
// 0-9, 9 being the highest level of compression
zipOutputStream.SetLevel(3);
foreach (string fileName in zipFileList) {
using(Stream fs = File.OpenRead(fileName)) {
var entry = new ZipEntry(ZipEntry.CleanName(fileName));
entry.Size = fs.Length;
// Setting the Size provides WinXP built-in extractor
// compatibility, but if not available, you can instead set
//zipOutputStream.UseZip64 = UseZip64.Off
zipOutputStream.PutNextEntry(entry);
int count = fs.Read(buffer, 0, buffer.Length);
while (count > 0) {
zipOutputStream.Write(buffer, 0, count);
count = fs.Read(buffer, 0, buffer.Length);
if (!Response.IsClientConnected) {
break;
}
Response.Flush();
}
}
}
}
Response.Flush();
Response.End();
}
' the aspx page has just one line e.g. <%@ Page language="vb" Codebehind=...
' but if you must run this from within a page that has other output, start with a Response.Clear()
Imports ICSharpCode.SharpZipLib.Zip
' This will accumulate each of the files named in the fileList into a zip file,
' and stream it to the browser.
' This approach writes directly to the Response OutputStream.
' The browser starts to receive data immediately which should avoid timeout problems.
' This also avoids an intermediate memorystream, saving memory on large files.
'
Private Sub DownloadZipToBrowser(zipFileList As List(Of String))
Response.ContentType = "application/zip"
' If the browser is receiving a mangled zipfile, IIS Compression may cause this problem. Some members have found that
'Response.ContentType = "application/octet-stream" has solved this. May be specific to Internet Explorer.
Response.AppendHeader("content-disposition", "attachment; filename=""Download.zip""")
response.CacheControl = "Private"
response.Cache.SetExpires(DateTime.Now.AddMinutes(3))
' or put a timestamp in the filename in the content-disposition
Dim buffer As Byte() = New Byte(4095) {}
Dim zipOutputStream As New ZipOutputStream(Response.OutputStream)
zipOutputStream.SetLevel(3) '0-9, 9 being the highest level of compression
For Each fileName As String In zipFileList
Dim fs As Stream = File.OpenRead(fileName)
' or any suitable inputstream
Dim entry As New ZipEntry(ZipEntry.CleanName(fileName))
entry.Size = fs.Length
' Setting the Size provides WinXP built-in extractor compatibility,
' but if not available, you can set zipOutputStream.UseZip64 = UseZip64.Off instead.
zipOutputStream.PutNextEntry(entry)
Dim count As Integer = fs.Read(buffer, 0, buffer.Length)
While count > 0
zipOutputStream.Write(buffer, 0, count)
count = fs.Read(buffer, 0, buffer.Length)
If Not Response.IsClientConnected Then
Exit While
End If
Response.Flush()
End While
fs.Close()
Next
zipOutputStream.Close()
Response.Flush()
Response.End()
End Sub