Can't parse ZIP contents with same stream-parsing logic as non-zipped content

6 posts, 1 answers
  1. Falafel Support
    Falafel Support avatar
    24 posts
    Member since:
    Sep 2009

    Posted 18 Nov 2011 Link to this post

    I have a Silverlight application that is importing Shape files (.shp) and parsing them as streams.  A shape file usually also include other companion files that have the same file name other than having a different extension (such as .dbf and .prj).  

    Because I want to be able to import these file groups directly or from within ZIPs, I wrote some logic to first add all the imported files to a list, then explode any imported zip files' file contents into that same list.  When I pass a ZipInputStream to my parsing logic, I get errors and strange behavior that I don't get when I import the files directly.  Here's the error I usually get:

    System.IO.EndOfStreamException: Attempted to read past the end of the stream.

    What am I doing wrong?  Why can't I just parse the ZipInputStreams the same way I parse the FileStreams that come from the OpenFileDialog?

    NOTE: Sample project is available here.  First try importing the sample data files directly (test.shp, test.dbf, test.prj) by multi-selecting them in the OpenFileDialog.  Then, try importing the ZIP file (test.zip) which contains the exact same three files and see the error.

    Thanks,
    J. Tower
  2. Falafel Support
    Falafel Support avatar
    24 posts
    Member since:
    Sep 2009

    Posted 22 Nov 2011 Link to this post

    Wondering if anyone at Telerik has had a chance to look at this yet?
  3. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 23 Nov 2011 Link to this post

    Hello J. Tower,

    You need to read from the ZipInputStream and based on the content you get, create a new stream which you can then use to implement your logic. Basically instead of passing the ZipPackageEntry.OpenInputStream() stream to the FileWrapper.Stream, you need to:
    foreach (var zipFile in zipFiles)
    {
        ZipPackage zip = ZipPackage.Open(zipFile.OpenRead(), FileAccess.Read);
        foreach (var file in zip.ZipPackageEntries)
        {
            StreamReader reader = new StreamReader(file.OpenInputStream());
            string streamContent = reader.ReadToEnd();
            Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(streamContent));
            allFiles.Add(new FileWrapper() { Name = file.FileNameInZip, Stream = stream });
        }
    }

    Please give this approach a try and let me know if it works for you.

    Best wishes,
    Tina Stancheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  4. Falafel Support
    Falafel Support avatar
    24 posts
    Member since:
    Sep 2009

    Posted 28 Nov 2011 Link to this post

    Tina,

    Thanks for the reply.  I tested your example and I think it proves the problem, actually.  If you read the files in from a ZIP using the ZipPackage class, you will notice that the stream lengths don't match the lengths you get when you read the exact same files in directly and uncompressed.  I added a few debug writelines to the project to show you.  It's available for download here.

    Here's the output of the stream lengths when read from the uncompressed files (without ZipPackage):
    test.shp:372
    test.dbf:188
    test.prj:425

    Here's the stream lengths from the same files, but compressed as a ZIP, and read with ZipPackage:
    test.shp:135
    test.dbf:35
    test.prj:246

    You'll also note that 2 of the 3 files are binary files, not UTF8 text files as your sample code was treating them.  I added some commented-out code to read the files all using a BinaryReader reader instead, but the stream lengths all still have the same problem in this code.

    Thanks, 

    J. Tower
  5. Answer
    Viktor Tsvetkov
    Admin
    Viktor Tsvetkov avatar
    382 posts

    Posted 29 Nov 2011 Link to this post

    Hi Telerik Downloads,

    I have modified your project to use the right logic for extracting streams from zips, so could you please examine it and tell me if you have some additional questions?

    Regards,
    Viktor Tsvetkov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  6. Falafel Support
    Falafel Support avatar
    24 posts
    Member since:
    Sep 2009

    Posted 29 Nov 2011 Link to this post

    That worked.  For those looking at this in the future, the keys seem to have been to:
    • Create a memory stream for each file in the zip
    • Use CopyTo() to read each file stream into the matching memory stream
    • Set the position of each memory stream to zero after the CopyTo()
Back to Top