/// <summary> /// Copy the contents of a stored file into an opened stream /// </summary> /// <param name="entry">Entry information of file to extract</param> /// <param name="_stream">Stream to store the uncompressed data</param> /// <returns>True if success, false if not.</returns> /// <remarks>Unique compression methods are Store and Deflate</remarks> public bool ExtractFile(ZipEntry entry, Stream stream) { if (!stream.CanWrite) { throw new InvalidOperationException("Stream cannot be written"); } // check signature byte[] signature = new byte[4]; this.zipFileStream.Seek(entry.HeaderOffset, SeekOrigin.Begin); this.zipFileStream.Read(signature, 0, 4); if (BitConverter.ToUInt32(signature, 0) != 0x04034b50) { return(false); } // Prepare streams stream.SetLength(entry.FileSize); var outStream = new CrcStream(stream); this.zipFileStream.Seek(entry.FileOffset, SeekOrigin.Begin); // Select input stream for inflating or just reading Stream inStream = new SegmentStream(this.zipFileStream, entry.CompressedSize); if (entry.Method == Compression.Deflate) { using (var intPutStream = new Ionic.Zlib.DeflateStream(inStream, Ionic.Zlib.CompressionMode.Decompress)) { intPutStream.FlushMode = FlushType.Full; int buffSize = 4096; byte[] buff = new byte[buffSize]; int size = 0; do { size = intPutStream.Read(buff, 0, buffSize); if (size > 0) { outStream.Write(buff, 0, size); } } while (size > 0); } //inStream = new DeflateStream(inStream, CompressionMode.Decompress, true); } // Decompress if (entry.Method == Compression.LZMA) { var decoder = new SevenZip.Compression.LZMA.Decoder(); const int PropsLength = 5; var buffer = new byte[PropsLength]; inStream.Read(buffer, 0, sizeof(int)); if (BitConverter.ToInt32(buffer, 0) != 0x00051409) { throw new Exception("Invalid LZMA stream signature"); } if (inStream.Read(buffer, 0, PropsLength) != PropsLength) { throw new Exception("Invalid LZMA properties length"); } decoder.SetDecoderProperties(buffer); decoder.Code(inStream, outStream, entry.CompressedSize, entry.FileSize, null); } else { inStream.CopyTo(outStream); } stream.Flush(); //if (entry.Method == Compression.Deflate) inStream.Dispose(); if (entry.Crc32 != outStream.WriteCrc) { throw new Exception("Uncompressed file CRC mismatch"); } return(true); }