Based on Alexei Levenkov and OP's comments, I've learned that it is possible to begin writing a zip file to a stream without having to completely assemble it before hand. Fortunately, .NET 4.5 provides a built in utility class for exactly this purpose: System.IO.Compression.ZipArchive.
Unfortunately, as described in this question, this class has a few incompatibilities with the HttpResponse.OutputStream which we intend to write to, since HttpResponse.OutputStream is not seekable, whereas ZipArchive requires any stream it writes to implement the Position member for a seekable stream. 
There is hope however: svick has posted an answer that diagnoses the issue and provides a way to work around it. The workaround involves simply creating a "go-between" stream, which implements the members ZipArchive requires, and simply forwards whatever is written to it into another stream (i.e. Response.OutputStream).
If you want to create the zip file server side, which I think is easier, you might want to look at the System.IO.Compression.ZipFile class, which provides static methods for creating archives from existing files.
Eg. creating an archive from a directory on the server:
// In ASP.NET, getting the UNC path to the directory which will be zipped
string dirpath = Server.MapPath('~/app/foldertodownload');
// Destination path
string destpath = Server.MapPath('~/public/downloads.zip');
ZipFile.CreateFromDirectory(dirpath, destpath);
Now all you need to do is write this zip file to the response with the appropriate headers.