<CharlieDigital/> Programming, Politics, and uhh…pineapples

2Apr/10Off

SharpZipLib and ASP.NET

I recently had to write a search-driven component to extract and export documents from a SharePoint repository. It presented a challenge since many examples on the web start from the premise of a file system and not binary streams.

I settled upon SharpZipLib, an excellent and fairly easy to use library, but found the documentation quite lacking, particularly around creating a zip file to a stream (like an ASP.NET output response stream).

I put together a little sample just to test it out and finally got it working after struggling with it for a good 30 minutes. This sample creates a zip package using an embedded resource (text file) for simplicity. In practice, you can just modify the implementation of the GetBinaryContent helper method. Note that when adding multiple files, you do a "put" first and then a "write".

using System;
using System.IO;
using System.Reflection;
using System.Web;
using System.Web.UI;
using ICSharpCode.SharpZipLib.Zip;
 

namespace SharpZipLibTest {
    public partial class _Default : Page {
        protected void Page_Load(object sender, EventArgs e) {
            string fileName = "package.zip";

            // Clear the response.
            Response.Clear();
            Response.Buffer = true;
            Response.ContentType = "application/octet-stream";
            Response.Charset = "";
            Response.AddHeader("Content-Disposition",
                string.Format("attachment; filename={0}", fileName));

            using (var ms = new MemoryStream()) 
            using (var zip = new ZipOutputStream(ms)) {
                byte[] fileBuffer = GetBinaryContent();

                // Write to the zip package.
                var entry = new ZipEntry("helloworld.txt");
                entry.DateTime = DateTime.Now;
                entry.Size = fileBuffer.Length;
                zip.PutNextEntry(entry);
                zip.Write(fileBuffer, 0, fileBuffer.Length);

                // Repeat for each file
                /*
                for(...) {
                    var entry = new ZipEntry("...");

                    zip.PutNextEntry(entry);
                    zip.Write(...);
                }
                */

                zip.Flush();
                zip.Finish();

                byte[] output = ms.ToArray();

                // Write the final output to the response stream.
                Response.OutputStream.Write(output, 0, output.Length);                
            }

            // End the response.
            Response.Flush();
            Response.End();

            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }

        /// <summary>
        /// Gets the binary content to send.
        /// </summary>
        /// <returns>The byte array containing the binary content.</returns>
        private byte[] GetBinaryContent() {
            string resourceName = "SharpZipLibTest.helloworld.txt";

            byte[] fileBuffer;

            using (Stream s = Assembly.GetExecutingAssembly()
                .GetManifestResourceStream(resourceName)) {
                // Read the file stream into a buffer.
                fileBuffer = new byte[s.Length];

                s.Read(fileBuffer, 0, fileBuffer.Length);
            }

            return fileBuffer;
        }
    }
}

The full project file is attached and runnable.

SharpZipLibTest.7z (104.3 KB)

Posted by Charles Chen

Filed under: .Net, DevTools Comments Off
Comments (0) Trackbacks (0)

Sorry, the comment form is closed at this time.

Trackbacks are disabled.