SharpZipLib create an archive with an in-memory string and download as an attachment
Asked Answered
A

1

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 ?

Asberry answered 12/1, 2012 at 5:5 Comment(0)
T
18

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);
Temperamental answered 12/1, 2012 at 5:57 Comment(4)
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.Lawler
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.Temperamental
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.Ozan
UTF8Encoding.Default.GetBytes is actually using the Default encoding for .Net. You should use Encoding.UTF8.GetBytes if you want to force UTF8.Tetrabasic

© 2022 - 2024 — McMap. All rights reserved.