Extract Nested Zips using Stream

Apr 27, 2009 at 9:02 PM
Edited Apr 27, 2009 at 9:09 PM
I need to be able to unzip nested zip files and only use streams.  Could someone please help me with this. 

Example file:
AAA.zip
->BBB.xml
->BBB.zip
->->CCC.ZIP
->->->DDD.ZIP


When I run the code below I get an exception when trying to do ZipFile.Read on the BBB.zip stream.

Message: 
"Could not read block - no data!  (position 0x000012EC)"

StackTrace:
"   at Ionic.Zip.SharedUtilities._ReadFourBytes(Stream s, String message)\r\n   at Ionic.Zip.SharedUtilities.ReadInt(Stream s)\r\n   at Ionic.Zip.ZipFile.VerifyBeginningOfZipFile(Stream s)\r\n   at Ionic.Zip.ZipFile.ReadIntoInstance(ZipFile zf)\r\n   at Ionic.Zip.ZipFile.Read(Stream zipStream, TextWriter statusMessageWriter, Encoding encoding, EventHandler`1 readProgress)\r\n   at Ionic.Zip.ZipFile.Read(Stream zipStream, TextWriter statusMessageWriter, Encoding encoding)\r\n   at Ionic.Zip.ZipFile.Read(Stream zipStream)\r\n   at SouthernCompany.SupplyChain.ProcessRFQ.Helper.ZipHelper.UnzipStream(Stream inputStream)"


Here is a dump of what the variables look like:

-  file {Ionic.Zip.ZipEntry} Ionic.Zip.ZipEntry
+  ActualEncoding null System.Text.Encoding
  BitField 8 short
  Comment null string
  CompressedSize 4744 long
  CompressionMethod 8 short
  CompressionRatio 2.0644095788604488 double
  Crc32 38137106 int
  Encryption None Ionic.Zip.EncryptionAlgorithm
  FileName "BBB.zip" string
  ForceNoCompression false bool
  IsDirectory false bool
+  LastModified {4/22/2009 1:18:36 PM} System.DateTime
  LocalFileName "BBB.zip" string
  OutputUsedZip64 null bool?
  OverwriteOnExtract false bool
+  ProvisionalAlternateEncoding {System.Text.SBCSCodePageEncoding} System.Text.Encoding {System.Text.SBCSCodePageEncoding}
  RequiresZip64 null bool?
  UncompressedSize 4844 long
  UsesEncryption false bool
  UseUnicodeAsNecessary false bool
  VersionNeeded 20 short
  WantCompression null Ionic.Zip.WantCompressionCallback
  WillReadTwiceOnInflation null Ionic.Zip.ReReadApprovalCallback

-  tempZip {System.IO.MemoryStream} System.IO.MemoryStream
+  base {System.IO.MemoryStream} System.IO.Stream {System.IO.MemoryStream}
  CanRead true bool
  CanSeek true bool
  CanWrite true bool
  Capacity 4844 int
  Length 4844 long
  Position 4844 long


public bool UnzipStream(Stream inputStream)

{

    try

    {

        bool success = true;

        ZipFile zip = ZipFile.Read(inputStream);

        MemoryStream tempFile = new MemoryStream();

        MemoryStream tempZip = new MemoryStream();

        foreach (ZipEntry file in zip)

        {

 

            if (file.FileName.ToLower().EndsWith(".zip"))

            {

                tempZip =

new MemoryStream();

 

 

                zip.Extract(file.FileName, tempZip);

 

                if (!UnzipStream(tempZip))

                {

                    success =

false;

 

 

                }

            }

 

            else

            {

                tempFile =

new MemoryStream();

 

 

                zip.Extract(file.FileName, tempFile);

 

                // Add logic for file

            }

        }

        zip.Dispose();

        return success;

    }

 

    catch (Exception ex)

    {

 

        return false;

    }

}

 

Apr 28, 2009 at 4:16 PM
I fixed the issue. It looks like when the zip file is written to the tempZip MemoryStream the position is set to the end of the stream, so just reset the position to zero.

zip.Extract(file.FileName, tempZip);

tempZip.Flush();

tempZip.Position = 0;

 

if (!UnzipStream(tempZip))

 

{

success =

false;

 

}

Coordinator
Apr 28, 2009 at 6:08 PM
Ahhh, glad you found the problem.