Reading Zip files from .NET 2.0

The .NET Framework 2.0 has Deflate and GZip implementations, but no support for Zip files. I want make a zip file available for download from a web server, and enable the server to open the archive and read the file contents.

The code uncompresses the first file in the zip archive.

using System; using System.IO; using System.IO.Compression; using System.Runtime.InteropServices; using System.Text; public static class Unzipper { // See Zip file specification for magic numbers etc. // http://www.pkware.com/businessanddevelopers/developer/appnote/ const uint LocalFileHeaderSignature = 0x04034b50; const int BytesToSkip = 2 + 2 + 2 + 2 + 2 + 4 + 4; const int BufferSize = 1<<14; // read chunks of 16k static uint SeekContents(Stream zipStream) { BinaryReader br = new BinaryReader(zipStream); uint uncompressedSize = 0; if (br.ReadUInt32() == LocalFileHeaderSignature) { // skip part of the header zipStream.Seek(BytesToSkip, SeekOrigin.Current); uncompressedSize = br.ReadUInt32(); ushort fileNameLength = br.ReadUInt16(); ushort extraFieldLength = br.ReadUInt16(); // the compressed contents is right after the header zipStream.Seek(fileNameLength + extraFieldLength, SeekOrigin.Current); } return uncompressedSize; } public static long Deflate(Stream outputStream, Stream compressedStream) { uint uncompressedSize = SeekContents(compressedStream); byte[] buf = new byte[BufferSize]; using (Stream decompressor = new DeflateStream(compressedStream, CompressionMode.Decompress)) { for (int i = 0; i < uncompressedSize; ) { // make sure we don't read past the stream int bytesToRead = ((i + BufferSize) > uncompressedSize) ? (int)(uncompressedSize % BufferSize) : BufferSize; int bytesRead = decompressor.Read(buf, 0, bytesToRead); if (bytesRead != bytesToRead) throw new InvalidDataException(); outputStream.Write(buf, 0, bytesRead); i += bytesRead; } } return uncompressedSize; } }

Google
m@kli.dk @klinkby RSS feed  GitHub