Zip.NET

I was enhancing my mp3 aspx search page to include a shopping cart function. I figured it would be nice to grab all of the mp3 files, zip them up into one big zip file and dump it into the HTTPResponse stream. Well two missing things: A zip library and a way to stream in the files so I don't have to create an actual hard disk based zip file. Here's how I did it:

The zip library can be found here -- SharpZipLib It's open source and a byproduct of the very cool open source SharpDevelop IDE.

Here's the code:

MemoryStream ms = new MemoryStream();
ZipOutputStream s = new ZipOutputStream( ms );
s.SetLevel(5); // 0 - store only to 9 - means best compression

foreach ( int id in ids ) // primary key ids
{
 
string location = new MP3DataAccess().GetLocation( id );
 
FileInfo fi = new FileInfo( location );
 
FileStream fs = File.OpenRead( location );
 
byte[] buffer = new byte[ fs.Length ];
 
fs.Read( buffer, 0, buffer.Length );
 
ZipEntry entry = new ZipEntry( fi.Name );
  s.PutNextEntry( entry );
 
s.Write( buffer, 0, buffer.Length );
}

s.Finish();
int streamLength = (int)ms.Length;
ms.Seek( 0, SeekOrigin.Begin );
ms.Position = 0;
byte[] buffinal = new byte[ streamLength ];
ms.Read( buffinal, 0, streamLength );
ms.Close();

Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/octet-stream";
Response.AppendHeader( "content-length", streamLength.ToString() );
string uniqueFileName = "mp3s-" + DateTime.Now.ToString( "yyyy-MM-ddTHHmmss" ) + ".zip";
Response.AppendHeader( "content-disposition", "inline; filename=" + uniqueFileName );
Response.BinaryWrite( buffinal );

Published Mon, Mar 29 2004 10:02 PM by craigg75
Filed under:

Comments

 

# re: Zip.NET

Thursday, April 01, 2004 1:00 AM by fractalnavel
can't you write the memory stream directly to the response object without having to write it to a byte array first ?
 

# re: Zip.NET

Thursday, April 01, 2004 8:29 AM by Craig
I tried that, but could never get it to work. A stream is a stream right? Couldn't find any examples of how to do it either. They all build the stream and dump the bytes into the Response.BinaryWrite method. I'm sure there's a way to directly write to it. Perhaps the Response stream cannot be dynamic in that it must be in place first? I've got a good ASP.Net book I dropped $40 on that hopefully will answer a lot of the questions I have on the subject, including this one.
 

# re: Zip.NET

Thursday, April 01, 2004 9:29 AM by fractalnavel
differences in the aspx vs. asp response, maybe. used to be you could serialize directly to response. with msxml, you could use

xmldoc.transformNodeToObject( xsldoc, Response )

has to do with an object's IPersist support more than streams, i think.
identicon: ip=127.0.0.1

# re: Zip.NET

Friday, April 02, 2004 3:51 AM by Number Six
I think the stream way is expecting text and not binary data which may mess up how it processes it to the browser.

I was just looking at a zip assembly from a well known maker of such components that does support streams. It may be worth looking into here as well. Expect an email on the subject.

I also just read in one of my books an example of using the gzip dll that IIS installs via interop and building it into your own Attribute class so you can bless WebServices with it to compress/decompress all the webservice xml traffic on the fly. Wayo cool if its truely compatible with java....

oh btw, you won't gain much compressing .mp3 files anyway. They're pretty close to compressed as is. Thats why newsgroopies flog posters who .rar their mp3's. Nothing to gain over the "1 missing piece blows the whole archive" exposure.

identicon: ip=127.0.0.1

# re: Zip.NET

Friday, April 02, 2004 3:53 AM by Number Six
Oh there is this bug in IIS that requires you to change a
metabase setting (the hard way, via code) before gzip will
work correctly on sending your stuff to the browser compressed.
I think I may have an URL to an article illustrating this bug
and fix in a forthcoming email.
 

# re: Zip.NET

Friday, April 02, 2004 8:25 AM by Craig
The only reason I'm using zip is provide a container for multiple mp3s. The whole idea of the one stop shopping cart. Download it all at once instead of seperate downloads. Setting compression to zero might speed up things too.

I like the idea of compressing xml messages in WS calls. Amazon could use that trick when you're pulling back hundreds of books on your wishlist via it's WS.

I think you're right about the browser expecting text. Also you need to tell the browser that this is a MIME type coming through so you have to preface the header with the type and then drop the bytes in. Just directing your stream to the Response output stream causes the browser to go woops.

Leave a Comment

(required) 
(required) 
(optional)
(required) 
identicon: ip=38.107.191.92
Please add 7 and 3 and type the answer here: