10

I use DotNetZip to create a zip archive with an in memory string and download it as an attachment with the following code.

byte[] formXml = UTF8Encoding.Default.GetBytes("<form><pkg>Test1</pkg></form>");
byte[] formHtml = UTF8Encoding.Default.GetBytes("<html><body>Test2</body></html>");

ZipFile zipFile = new ZipFile();
zipFile.AddEntry("Form.xml", formXml);
zipFile.AddEntry("Form.html", formHtml);
Response.ClearContent();
Response.ClearHeaders();
Response.AppendHeader("content-disposition", "attachment; filename=FormsPackage.zip");
zipFile.Save(Response.OutputStream); 
zipFile.Dispose();

Now I have a requirement to do the same with SharpZipLib. How can I do it ? Does SharpZipLib support adding files as array of bytes ?

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Dimuthu
  • 326
  • 2
  • 8
  • 25

1 Answers1

17

Try below

MemoryStream msFormXml = new MemoryStream(UTF8Encoding.Default.GetBytes("<form><pkg>Test1</pkg></form>"));
MemoryStream msFormHTML = new MemoryStream(UTF8Encoding.Default.GetBytes("<html><body>Test2</body></html>"));

MemoryStream outputMemStream = new MemoryStream();
ZipOutputStream zipStream = new ZipOutputStream(outputMemStream);

zipStream.SetLevel(3); //0-9, 9 being the highest level of compression

ZipEntry xmlEntry = new ZipEntry("Form.xml");
xmlEntry.DateTime = DateTime.Now;
 zipStream.PutNextEntry(xmlEntry);
StreamUtils.Copy(msFormXml, zipStream, new byte[4096]);
zipStream.CloseEntry();

ZipEntry htmlEntry = new ZipEntry("Form.html");
htmlEntry.DateTime = DateTime.Now;
zipStream.PutNextEntry(htmlEntry);
StreamUtils.Copy(msFormHTML, zipStream, new byte[4096]);
zipStream.CloseEntry();

zipStream.IsStreamOwner = false; 
zipStream.Close(); 

outputMemStream.Position = 0;

byte[] byteArray = outputMemStream.ToArray();

Response.Clear();
Response.AppendHeader("Content-Disposition", "attachment; filename=FormsPackage.zip");
Response.AppendHeader("Content-Length", byteArray.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.BinaryWrite(byteArray);
  • So once the request finishes and the download finishes, is the memory freed? I'm also doing something very similar, and there can be lots of files. I need the memory cleared after the request finishes. I'm pretty sure the garbage collector would take care of it, but I'm not 100% sure. – harsimranb Apr 07 '14 at 17:14
  • Garbage collector is suppose to do it. But for data types such as "MemoryStream", you have to be calling Dispose() or use "using" statements to guarantee the memory is freed. – Chathuranga Wijeratna Apr 08 '14 at 03:37
  • Just wanted to add a comment for someone else. If not all of the streams are being added at the same time StreamUtils.Copy was not working for me. I had to go with zipStream.Write(content, 0, content.length); (content is the byte[] of the file stream) Otherwise good answer and upvote. – Tony Jun 12 '14 at 15:37
  • UTF8Encoding.Default.GetBytes is actually using the Default encoding for .Net. You should use Encoding.UTF8.GetBytes if you want to force UTF8. – Paul Kiar Apr 22 '19 at 16:22