Concept:
1. Open a Package to create a zip file
2. Create a Package Part(URL of the file to add) inside the Package
3. Read the bytes of file to add & add its file stream to the Package
4. Output the zip file with file stream
Code:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.IO.Packaging;
using System.Net.Mime;
namespace TEA
{
public partial class WebForm1 : System.Web.UI.Page
{
private const long BUFFER_SIZE = 4096;
protected void Page_Load(object sender, EventArgs e)
{
string zipFileDiectory = "/temp/";
string outputFileName = "download.zip";
string zipFileName = Server.MapPath(zipFileDiectory + outputFileName);
bool is_OK = true;
is_OK &= this.addFileToZip(zipFileName, Server.MapPath("/stafflan/U2810_A4 brochure_AQA Feb2010 v5.pdf"), true);
is_OK &= this.addFileToZip(zipFileName, Server.MapPath("/stafflan/Winter.jpg"), false);
if (is_OK == true)
{
FileStream liveStream = new FileStream(zipFileName, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[(int)liveStream.Length];
liveStream.Read(buffer, 0, (int)liveStream.Length);
liveStream.Close();
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Length", buffer.Length.ToString());
Response.AddHeader("Content-Disposition", "attachment; filename=" +
outputFileName);
Response.BinaryWrite(buffer);
}
Response.Write("Compression failed!");
Response.End();
}
private bool addFileToZip(string zipFile, string inputFile, bool is_clearZip)
{
// check if the input file exists
if (File.Exists(inputFile) == false)
{
return false;
}
if(File.Exists(zipFile) == false)
{
Directory.CreateDirectory(Path.GetDirectoryName(zipFile));
}
else if (is_clearZip == true)
{
File.Delete(zipFile);
}
Package package_zip = ZipPackage.Open(zipFile, FileMode.OpenOrCreate, FileAccess.ReadWrite);
string fileInZip = Path.GetFileName(inputFile);
Uri uri_fileInZip = PackUriHelper.CreatePartUri(new Uri(fileInZip, UriKind.Relative));
// if there is existing same name file in the zip, delete it
if(package_zip.PartExists(uri_fileInZip))
{
package_zip.DeletePart(uri_fileInZip);
}
PackagePart packagePart_zip = package_zip.CreatePart(uri_fileInZip, MediaTypeNames.Application.Zip, CompressionOption.Normal);
FileStream fileStream_input = new FileStream(inputFile, FileMode.Open, FileAccess.Read);
Stream stream_output = packagePart_zip.GetStream();
this.copyStream(ref fileStream_input, ref stream_output);
stream_output.Close();
fileStream_input.Close();
package_zip.Close();
return true;
}
private void copyStream(ref FileStream inputStream, ref Stream outputStream)
{
long bufferSize = inputStream.Length < buffer =" new" bytesread =" 0;" byteswritten =" 0;" bytesread =" inputStream.Read(buffer,">
Limitation:
- include automatically "[Content_Types].xml" in the zip file
- cannot create directory inside the zip file
- compression rate is not good
- cannot zip big files larger than Int32
References:
1. http://weblogs.asp.net/jgalloway/archive/2007/10/25/creating-zip-archives-in-net-without-an-external-library-like-sharpziplib.aspx?CommentPosted=true#commentmessage
2. http://www.emoreau.com/Entries/Articles/2008/08/Introducing-SystemIOPackaging.aspx
Solution:
Use DotNetZip Library instead
Code:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Ionic.Zip;
using System.IO;
namespace TEA
{
public partial class WebForm1 : System.Web.UI.Page
{
private const long BUFFER_SIZE = 4096;
protected void Page_Load(object sender, EventArgs e)
{
string zipFileDiectory = "/tea/bin/written_brief_file/";
string outputFileName = "download.zip";
string zipFileName = Server.MapPath(zipFileDiectory + outputFileName);
/*
using (ZipFile zipFile = new ZipFile())
{
// add this map file into the "images" directory in the zip archive
zipFile.AddFile(Server.MapPath("/stafflan/U2810_A4 brochure_AQA Feb2010 v5.pdf"), ".");
// add the report into a different directory in the archive
zipFile.AddDirectory(Server.MapPath("/stafflan/FluorineFXTest/"), "FluorineFXTest");
zipFile.Save(zipFileName);
}
*/
// zip all file in a folder
using (ZipFile zipFile = new ZipFile())
{
zipFile.AddDirectory(Server.MapPath("/stafflan"), "");
zipFile.Save(zipFileName);
}
// output files
FileStream liveStream = new FileStream(zipFileName, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[(int)liveStream.Length];
liveStream.Read(buffer, 0, (int)liveStream.Length);
liveStream.Close();
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Length", buffer.Length.ToString());
Response.AddHeader("Content-Disposition", "attachment; filename=" +
outputFileName);
Response.BinaryWrite(buffer);
Response.End();
}
}
}
References:
1. http://dotnetzip.codeplex.com/ (API)