0

I'm trying on c# to download a zip file from a webservice and extract an entry in the memory but when I try to read the stream how is in the documentation of the dotnetzip I get the exception "This stream does not support seek operations” in the "ZipFile.Read(stream)" part.

Somebody could tell me what I'm doing wrong? Thanks in advance

urlAuthentication="https://someurl/?login=foo&token=faa"
var request = (HttpWebRequest)WebRequest.Create(urlAuthentication);

request.Proxy = WebRequest.DefaultWebProxy;
request.Credentials = System.Net.CredentialCache.DefaultCredentials; ;
request.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;


using (var ms = new MemoryStream())
{

   using (var response = (HttpWebResponse)request.GetResponse())
   {


      using (var stream =response.GetResponseStream())
      {

        using (ZipFile zipout = ZipFile.Read(stream))
        {
            ZipEntry entry = zipout["file1.xml"];
            entry.Extract(ms);
        }

      }
    }

}
rlartiga
  • 429
  • 5
  • 21
  • What are some example sizes of the zip file and xml inside it? Does the zip contain much besides the target xml file? Maybe it'd be easier if you read the whole zip file into a `MemoryStream` or `byte[]` and then fed that to the `ZipFile` class. – Tim S. Aug 12 '14 at 17:13
  • @TimS. The zip file size is 17kb and have two files of 182kb and 25.3 kb respectively (the entry I want to acess is the one of 182kb) – rlartiga Aug 12 '14 at 17:18

1 Answers1

1

Apparently dotnetzip requires a stream to support seek operations and the response stream of a HttpWebResponse does not support seeking.

You can solve this issue by first downloading the entire file in memory, and then accessing it:

using (var ms = new MemoryStream())
{
    using (MemoryStream seekable = new MemoryStream())
    {
        using (var stream = response.GetResponseStream())
        {
            int bytes;
            byte[] buffer = new byte[1024];
            while ((bytes = stream.Read(buffer, 0, buffer.Length)) > 0)
            {
                seekable.Write(buffer, 0, bytes);
            }
        }

        seekable.Position = 0;
        using (ZipFile zipout = ZipFile.Read(seekable))
        {
            ZipEntry entry = zipout["file1.xml"];
            entry.Extract(ms);
        }
    }

    // access ms
}
C.Evenhuis
  • 25,996
  • 2
  • 58
  • 72
  • 2
    If using .NET 4 or greater, you should be able to replace your loop with a `CopyTo` call, e.g. `stream.CopyTo(seekable)`. http://msdn.microsoft.com/en-us/library/system.io.stream.copyto(v=vs.110).aspx – Tim S. Aug 12 '14 at 17:21