tags:

views:

294

answers:

2

I have a method

private static String DecompressAndDecode(byte[] data)
{
   GZipStream decompressor = new GZipStream(new MemoryStream(data), CompressionMode.Decompress);
   StreamReader decompressed = new StreamReader(decompressor, Encoding.UTF8);
   String result = decompressed.ReadToEnd();
   return result;
}

I have some GZipped text as input and the result is supposed to be a String representation of this text. The problem is that the method returns an empty string. What is puzzling me is that when I step trough the method in debug mode and reach the return statement the result variable is an empty string but if I create a watch for the decompressed.ReadToEnd() expression it returns me the text. What I would expect at this point is the result variable to contain the text and the decompressed.ReadToEnd() expression evaluating to an empty string. (Reevaluating the decompressed.ReadToEnd() expression returns an empty string as expected).

@Edit: I have found that in my case ReadToEnd() returns the text on the second call returning empty strings on the first call and after the second call.

There must be something obvious I'm missing here.

+1  A: 

"There must be something obvious I'm missing here." - maybe, and so am I ;-)
Let's start with a little self-contained example and see where it differs from your actual code.

class SOTest
{
  private static String DecompressAndDecode(byte[] data)
  {
    GZipStream decompressor = new GZipStream(new MemoryStream(data), CompressionMode.Decompress);
    StreamReader decompressed = new StreamReader(decompressor, Encoding.UTF8);
    String result = decompressed.ReadToEnd();
    return result;
  }

  private static byte[] foo(string data)
  {
    MemoryStream dest = new MemoryStream();
    using (GZipStream compressor = new GZipStream(dest, CompressionMode.Compress))
    {
      using (StreamWriter sw = new StreamWriter(compressor))
      {
        sw.Write(data);
      }
    }
    return dest.GetBuffer();
  }


  static void Main()
  {
    System.Console.WriteLine(
      DecompressAndDecode(foo("Mary had a little lamb."))
    );
    return;
  }
}

prints Mary had a little lamb.

VolkerK
Thanks for your help! Your example works. The only difference in my case I'm getting the data from a SQL database with a SqlDataReader and the text is quite a bit longer and has some non-ascii characters. I have found that _in my case_ ReadToEnd returns the text on the second call.
axk
Does this only happen with longer data or can you reduce the amount of data (passed to DecompressAndDecode(byte[]) for debugging purposes?
VolkerK
+1  A: 

I think your problem is the position of the pointer in the steam. Each time after you perform the readToEnd, the pointer is set to the end that is why you can watch it first time.

Run the following code before readToEnd to set the pointer to the beginning. someStream.Seek(0, SeekOrigin.Begin)

Fuji