public void ExtractEntry(Entry entry, Stream outputStream, ZipProgressHandler progressHandler = null)
{
if (entry.Offset >= _Stream.Length)
throw new Exception("Invalid ZIP entry offset");
_Stream.Seek(entry.Offset, SeekOrigin.Begin);
byte[] buffer = new byte[1024 * 1024];
_Stream.Read(buffer, 0, 30);
ushort fileNameLength = BitConverter.ToUInt16(buffer, 26);
ushort extraFieldLength = BitConverter.ToUInt16(buffer, 28);
_Stream.Seek(entry.Offset + 30 + fileNameLength + extraFieldLength, SeekOrigin.Begin);
Stream dataStream;
switch (entry.CompressionMethod)
{
case 0:
dataStream = _Stream;
break;
case 8:
dataStream = new System.IO.Compression.DeflateStream(_Stream, System.IO.Compression.CompressionMode.Decompress, true);
break;
default:
throw new Exception("Unsupported ZIP compression method: " + entry.CompressionMethod + " for " + entry.FileName);
}
uint done = 0;
while (done < entry.UncompressedSize)
{
int todo = (int)Math.Min(entry.UncompressedSize - done, (uint)buffer.Length);
if (dataStream.Read(buffer, 0, todo) != todo)
throw new Exception("Cannot read data from ZIP stream for " + entry.FileName);
outputStream.Write(buffer, 0, todo);
done += (uint)todo;
if (progressHandler != null)
progressHandler(done, entry.UncompressedSize);
}
if (dataStream != _Stream)
dataStream.Dispose();
}