3

UnZipFile method writes the data from inputStream to outputWriter. Why sr.ToString() returns System.Byte[] and not the data?

using (var sr = new StringWriter())
{
    UnZipFile(response.GetResponseStream(), sr);
    var content = sr.ToString();
}


public static void UnZipFile(Stream inputStream, TextWriter outputWriter)
{
    using (var zipStream = new ZipInputStream(inputStream))
    {
        ZipEntry currentEntry;
        if ((currentEntry = zipStream.GetNextEntry()) != null)
        {
            var size = 2048;
            var data = new byte[size];
            while (true)
            {
                size = zipStream.Read(data, 0, size);
                if (size > 0)
                {
                    outputWriter.Write(data);                       
                }
                else
                {
                    break;
                }
            }
        }
    }
}
theateist
  • 13,879
  • 17
  • 69
  • 109
  • Looks like data *is* in fact a `System.byte[]`. More so since it looks like a binary file. – Alex Sep 10 '12 at 15:13
  • I'm surprised that the Zip tools work at all on a ResponseStream, it has `CanSeek=false` . – H H Sep 10 '12 at 15:33
  • possible duplicate of [How to extract zipped file received from HttpWebResponse?](http://stackoverflow.com/questions/12350670/how-to-extract-zipped-file-received-from-httpwebresponse) – H H Sep 11 '12 at 16:18

3 Answers3

5

The problem is on the line:

outputWriter.Write(data); 

StringWriter.Write has no overload expecting a byte[]. Therefore, Write(Object) is called instead. And according to MSDN:

Writes the text representation of an object to the text string or stream by calling the ToString method on that object.

Calling ToString on a byte array returns System.byte[], explaining how you get that string in your StringWriter.

Kevin Gosse
  • 38,392
  • 3
  • 78
  • 94
1

The reason is simple:

data is of type byte[]. There is no overload for byte[] on StringWriter so it uses the overload for object. And then calls ToString() on the boxed byte array which simply prints the type.

Your code is equivalent to this:

outputWriter.Write(data.ToString());
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
0

theateist,

Looking at the other answers here, I am going to have to agree that the reason for the "ToString()" returning System.Byte[] is because that is what you are putting into it, and everything put into the StringWriter calls it's own "ToString" method when doing so. (i.e. byte[].toString() = "System.byte[]"). In fact the whole idea is that the StringWriter is only ment for writing into a string "buffer" (StringBuilder), so in theory if your file was large enough(bigger than 2048), your output would be "System.Byte[]System.Byte[]" (etc.). Try this to deflate into a memory stream and then read from that stream, may be a better understanding of what you are looking at. (Code not tested, just example).

using (Stream ms = new MemoryStream())  
{
    UnZipFile(response.GetResponseStream(), ms);

    string content;

    ms.Position = 0;
    using(StreamReader s = new StreamReader(ms))
    {
        content = s.ReadToEnd();
    } 
}

public static void UnZipFile(Stream inputStream, Stream outputWriter)
{      
    using (var zipStream = new ZipInputStream(inputStream))
    {
        ZipEntry currentEntry;
        if ((currentEntry = zipStream.GetNextEntry()) != null)
        {
            int size = 2048;
            byte[] data = new byte[size]; 
            while (true)
            {
                size = zipStream.Read(data, 0, size);
                if (size > 0)
                {
                    outputWriter.Write(data);
                }
                else
                {
                    break;
                }
            }
        }
    }
}

Another idea would actually be to using the endcoding to get the string

public string UnZipFile(Stream inputStream)
{
    string tmp;

    using(Stream zipStream = new ZipInputStream(inputStream))
    {
        ZipEntry currentEntry;

        if(currentEntry = zipStream.GetNextEntry()) != null)
        {
            using(Stream ms = new MemoryStream())
            {
                int size = 2048;
                byte[] data = new byte[size];
                while(true)
                {
                    if((size = zipStream.Read(data,0,size)) > 0)
                        ms.Write(data);
                    else
                        break;
                }
                tmp = Encoding.Default.GetString(ms.ToByteArray());
                }
            }
        }
    }
    return tmp;
}

Or as one last idea, you could actually change your original code to have

outputWriter.Write(Encoding.Default.GetString(data));

Instead of

outputWriter.Write(data);

By the way, please avoid the var keyword in posts, maybe just my pet peev, but code is less readable when utilizing weak types.

StringWriter.Write:MSDN StringWriter.ToString:MSDN

iMortalitySX
  • 1,478
  • 1
  • 9
  • 23