3

I put url to browser's address bar and it downloads the zip file to HD. The size of zipped file is 386 bytes as written in its properties.

When I use UnZipFiles method to extract the file - it works. But, I want to download programaticaly and extract it in memory. I use GetResultFromServer method to get zipped content. As shown in headers the size of the content is the same as the size of zipped file saved on HD:

content-disposition: attachment; filename=emaillog-xml.zip
Content-Length: 386
Cache-Control: private
Content-Type: application/zip
Date: Mon, 10 Sep 2012 08:28:28 GMT
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET

My question is how to extract the content returned by GetResultFromServer? I tried the following:

var ms = new MemoryStream(Encoding.Unicode.GetBytes(res))
var s = new ZipInputStream(ms);

but I get Unable to read from this stream.

UPDATED

I tried var zipStream = new System.IO.Compression.GZipStream(response.GetResponseStream(), CompressionMode.Decompress) but I get The magic number in GZip header is not correct error

Code

private string GetResultFromServer(ElasticLogParams elasticLogParams)
{        
    var webRequest = (HttpWebRequest)WebRequest.Create(url);            
    var response = webRequest.GetResponse();

    using (var reader = new StreamReader(response.GetResponseStream()))
    {
        var res = reader.ReadToEnd();
        var headers = response.Headers.ToString();              

        return res;
    }
}

public static void UnZipFiles(string zippedFilePath, Stream stream = null)
{
    var s = new ZipInputStream(stream ?? File.OpenRead(zippedFilePath));

    ZipEntry theEntry;
    while ((theEntry = s.GetNextEntry()) != null)
    {
        using (var streamWriter = File.Create(@"D:\extractedXML.xml"))
        {
            var size = 2048;
            var data = new byte[size];
            while (true)
            {
                size = s.Read(data, 0, size);
                if (size > 0)
                {
                    streamWriter.Write(data, 0, size);
                }
                else
                {
                    break;
                }
            }
            streamWriter.Close();
        }
    }
    s.Close();
}
theateist
  • 13,879
  • 17
  • 69
  • 109
  • 2
    Did you try `var s = new ZipInputStream(response.GetResponseStream());`? – Rowland Shaw Sep 10 '12 at 11:29
  • @Rowland, it didn't worked. Maybe I need to use `System.IO.Compression.GZipStream`? – theateist Sep 10 '12 at 11:37
  • I tried `var zipStream = new System.IO.Compression.GZipStream(response.GetResponseStream(), CompressionMode.Decompress)` but I get `The magic number in GZip header is not correct` error – theateist Sep 10 '12 at 11:41
  • @Rowland Shaw, I don't know why it didn't worked at first time, but now it works. I gave you credit in Mike's answer – theateist Sep 10 '12 at 14:06

2 Answers2

3

Give this a shot:

var response = webRequest.GetResponse() as HttpWebResponse;
var stream = response.GetResponseStream();
var s = new ZipInputStream(stream);

I believe you're very close and that you're using the right approach -- you can use this article to back that up -- their code is very similar.

Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
Mike Perrenoud
  • 66,820
  • 29
  • 157
  • 232
  • I tried `var chars = new char[response.ContentLength]; reader.Read(chars, 0, (int)response.ContentLength); var bytes = Encoding.ASCII .GetBytes(chars); var ms = new MemoryStream(bytes); UnZipFiles(null, ms);` but I get `Unknown block type 7` error – theateist Sep 10 '12 at 12:03
  • If I try `var bytes = Encoding.UTF8.GetBytes(chars);` the size of returned bytes is 621 instead of 386 – theateist Sep 10 '12 at 12:04
  • What happens if you run the example I provided as is? Do you get an error when sending the `byte[]` in directly into the `MemoryStream` and then sending the `MemoryStream` into the `ZipInputStream`? – Mike Perrenoud Sep 10 '12 at 12:37
  • `response` doesn't have `Read` method and therefore I use `reader` – theateist Sep 10 '12 at 12:43
  • Oh, I think the issue is that you just need to cast the repsonse to an `HttpWebResponse`. – Mike Perrenoud Sep 10 '12 at 12:48
  • I'm sorry but `HttpWebResponse` doesn't have `Read` method – theateist Sep 10 '12 at 13:12
  • I've edited my answer, please try those three lines of code. I meant to add the `GetResponseStream` call into the mix and missed it. Guess that's what you get for writing the code online. Sorry. – Mike Perrenoud Sep 10 '12 at 13:47
  • Yes, it works! But, now don't understand why it didn't worked previously when @Rowland Shaw suggested the same thing! Very strange. Anyway it works now! – theateist Sep 10 '12 at 14:04
  • Great! I'm glad I could be of some help! – Mike Perrenoud Sep 10 '12 at 14:11
0

I'm using http://dotnetzip.codeplex.com/ I've not used it to download stuff, but to extract stuff that people upload to my server. I assume it should work perfectly the other way round too.

I've tried the built-in zip from microsoft too, but also had issues. So I gave it up and switched.

Remy
  • 12,555
  • 14
  • 64
  • 104
  • but you need to save the file on HD first. And I don't want to save it on HD but extract as soon I downloaded via `HttpWebResponse` – theateist Sep 10 '12 at 11:45