Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot create DotNetZip ZipFile from file download via HTTP Response

I am try to download a zip file via a url to extract files from. I would rather not have to save it a temp file (which works fine) and rather keep it in memory - it is not very big. For example, if I try to download this file:

http://phs.googlecode.com/files/Download%20File%20Test.zip

using this code:

using Ionic.Zip;
...
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

if (response.ContentLength > 0)
{
    using (MemoryStream zipms = new MemoryStream())
    {
        int bytesRead;
        byte[] buffer = new byte[32768];

        using (Stream stream = response.GetResponseStream())
        {
            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
                zipms.Write(buffer, 0, bytesRead);

            ZipFile zip = ZipFile.Read(stream); // <--ERROR: "This stream does not support seek operations. "
        }

        using (ZipFile zip = ZipFile.Read(zipms)) // <--ERROR: "Could not read block - no data!  (position 0x00000000) "
        using (MemoryStream txtms = new MemoryStream())
        {
            ZipEntry csentry= zip["Download File Test.cs"];
            csentry.Extract(txtms);
            txtms.Position = 0;
            using (StreamReader reader = new StreamReader(txtms))
            {
                string csentry = reader.ReadToEnd();
            }
        }
    }
}
...

Note where i flagged the errors I am receiving. With the first one, it does not like the System.Net.ConnectStream. If I comment that line out and allow it to hit the line where I note the second error, it does not like the MemoryStream. I did see this posting: https://stackoverflow.com/a/6377099/1324284 but I am having the same issues that others mention about not having more then 4 overloads of the Read method so I cannot try the WebClient.

However, if I do everything via a FileStream and save it to a temp location first, then point ZipFile.Read at that temp location, everything works including extracting any contained files into a MemoryStream.

Thanks for any help.

like image 854
Ernie S Avatar asked Jan 31 '26 17:01

Ernie S


1 Answers

You need to Flush() your MemoryStream and set the Position to 0 before you read from it, otherwise you are trying to read from the current position (where there is nothing).

For your code:

ZipFile zip;
using (Stream stream = response.GetResponseStream())
{
    while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
        zipms.Write(buffer, 0, bytesRead);
    zipms.Flush();
    zipms.Position = 0;
    zip = ZipFile.Read(zipms);
}
like image 63
Halvard Avatar answered Feb 02 '26 07:02

Halvard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!