C# | Visual Basic | Visual C++ |
public CrcCalculatorStream OpenReader()
Public Function OpenReader As CrcCalculatorStream
public: CrcCalculatorStream^ OpenReader()
DotNetZip offers a variety of ways to extract entries from a zip file. This method allows an application to extract an entry by reading a Stream.
The return value is of type CrcCalculatorStream. Use it as you would any stream for reading. When an application calls Read(array<Byte>[]()[][], Int32, Int32) on that stream, it will receive data from the zip entry that is decrypted and decompressed as necessary.
CrcCalculatorStream adds one additional feature: it keeps a CRC32 checksum on the bytes of the stream as it is read. The CRC value is available in the Crc property on the CrcCalculatorStream. When the read is complete, your application should check this CRC against the Crc property on the ZipEntry to validate the content of the ZipEntry. You don't have to validate the entry using the CRC, but you should, to verify integrity. Check the example for how to do this.
If the entry is protected with a password, then you need to provide a password prior to calling OpenReader()()()(), either by setting the Password property on the entry, or the Password property on the ZipFile itself. Or, you can use OpenReader(String), the overload of OpenReader that accepts a password parameter.
If you want to extract entry data into a write-able stream that is already opened, like a FileStream, do not use this method. Instead, use Extract(Stream).
Your application may use only one stream created by OpenReader() at a time, and you should not call other Extract methods before completing your reads on a stream obtained from OpenReader(). This is because there is really only one source stream for the compressed content. A call to OpenReader() seeks in the source stream, to the beginning of the compressed content. A subsequent call to OpenReader() on a different entry will seek to a different position in the source stream, as will a call to Extract() or one of its overloads. This will corrupt the state for the decompressing stream from the original call to OpenReader().
The OpenReader() method works only when the ZipEntry is obtained from an instance of ZipFile. This method will throw an exception if the ZipEntry is obtained from a ZipInputStream.
using (ZipFile zip = new ZipFile(ZipFileToRead)) { ZipEntry e1= zip["Elevation.mp3"]; using (Ionic.Zlib.CrcCalculatorStream s = e1.OpenReader()) { byte[] buffer = new byte[4096]; int n, totalBytesRead= 0; do { n = s.Read(buffer,0, buffer.Length); totalBytesRead+=n; } while (n>0); if (s.Crc32 != e1.Crc32) throw new Exception(string.Format("The Zip Entry failed the CRC Check. (0x{0:X8}!=0x{1:X8})", s.Crc32, e1.Crc32)); if (totalBytesRead != e1.UncompressedSize) throw new Exception(string.Format("We read an unexpected number of bytes. ({0}!={1})", totalBytesRead, e1.UncompressedSize)); } }
Using zip As New ZipFile(ZipFileToRead) Dim e1 As ZipEntry = zip.Item("Elevation.mp3") Using s As Ionic.Zlib.CrcCalculatorStream = e1.OpenReader Dim n As Integer Dim buffer As Byte() = New Byte(4096) {} Dim totalBytesRead As Integer = 0 Do n = s.Read(buffer, 0, buffer.Length) totalBytesRead = (totalBytesRead + n) Loop While (n > 0) If (s.Crc32 <> e1.Crc32) Then Throw New Exception(String.Format("The Zip Entry failed the CRC Check. (0x{0:X8}!=0x{1:X8})", s.Crc32, e1.Crc32)) End If If (totalBytesRead <> e1.UncompressedSize) Then Throw New Exception(String.Format("We read an unexpected number of bytes. ({0}!={1})", totalBytesRead, e1.UncompressedSize)) End If End Using End Using