/// <summary> /// UnZip files from zip archive in a stream. /// </summary> /// <param name="zipStream">Zip archive stream.</param> /// <returns>Each file in the archive.</returns> public static IEnumerable <UncompressedFile> UnZip(Stream zipStream) { BinaryReader binaryReader = new BinaryReader(zipStream); LimitedStream limitedStream = new LimitedStream(zipStream, 0); while (true) { uint signature = binaryReader.ReadUInt32(); if (signature == 0x02014b50) { break; } if (signature != 0x04034b50) { throw new ApplicationException("Zip file is broken or corrupt"); } binaryReader.ReadBytes(2); ushort flags = binaryReader.ReadUInt16(); if ((flags & (1 << 3)) != 0) { throw new ApplicationException("Unsupported Zip file format (compressed size not available in header"); } ushort method = binaryReader.ReadUInt16(); binaryReader.ReadBytes(8); uint compressedSize = binaryReader.ReadUInt32(); binaryReader.ReadBytes(4); ushort fileNameLength = binaryReader.ReadUInt16(); ushort extraFieldLength = binaryReader.ReadUInt16(); string filename = Encoding.ASCII.GetString(binaryReader.ReadBytes(fileNameLength)).Replace('/', Path.DirectorySeparatorChar); binaryReader.ReadBytes(extraFieldLength); limitedStream.Limit = compressedSize; switch (method) { case 0: // No compression yield return(new UncompressedFile(filename, limitedStream)); break; case 8: // Deflate DeflateStream deflateStream = new DeflateStream(limitedStream, CompressionMode.Decompress, true); yield return(new UncompressedFile(filename, deflateStream)); break; default: // Ignore... break; } limitedStream.SeekToEnd(); } limitedStream.Close(); binaryReader.Close(); }