This is a migrated thread and some comments may be shown as answers.

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

5 Answers 188 Views
ZipLibrary
This is a migrated thread and some comments may be shown as answers.
Falafel Support
Top achievements
Rank 1
Falafel Support asked on 18 Nov 2011, 05:05 PM
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

5 Answers, 1 is accepted

Sort by
0
Falafel Support
Top achievements
Rank 1
answered on 22 Nov 2011, 07:21 PM
Wondering if anyone at Telerik has had a chance to look at this yet?
0
Tina Stancheva
Telerik team
answered on 23 Nov 2011, 05:21 PM
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 >>

0
Falafel Support
Top achievements
Rank 1
answered on 28 Nov 2011, 05:28 PM
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
0
Accepted
Viktor Tsvetkov
Telerik team
answered on 29 Nov 2011, 03:45 PM
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 >>

0
Falafel Support
Top achievements
Rank 1
answered on 29 Nov 2011, 05:20 PM
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()
Tags
ZipLibrary
Asked by
Falafel Support
Top achievements
Rank 1
Answers by
Falafel Support
Top achievements
Rank 1
Tina Stancheva
Telerik team
Viktor Tsvetkov
Telerik team
Share this question
or