StreamReader ReadToEnd() returns empty string on first attempt

Victor Cassel picture Victor Cassel · Dec 16, 2010 · Viewed 12k times · Source

I know this question has been asked before on Stackoverflow, but could not find an explanation.

When I try to read a string from a compressed byte array I get an empty string on the first attempt, on the second I succed and get the string.

Code example:

public static string Decompress(byte[] gzBuffer)
{
    if (gzBuffer == null)
        return null;
    using (var ms = new MemoryStream(gzBuffer))
    {
        using (var decompress = new GZipStream(ms, CompressionMode.Decompress))
        {
            using (var sr = new StreamReader(decompress, Encoding.UTF8))
            {
                string ret = sr.ReadToEnd();
                // this is the extra check that is needed !?
                if (ret == "")
                    ret = sr.ReadToEnd();
                return ret;
            }
        }
    }
}

All suggestions are appreciated. - Victor Cassel

Answer

Victor Cassel picture Victor Cassel · Dec 17, 2010

I found the bug. It was as Michael suggested in the compression routine. I missed to call Close() on the GZipStream.

public static byte[] Compress(string text)
{
    if (string.IsNullOrEmpty(text))
        return null;

    byte[] raw = Encoding.UTF8.GetBytes(text);
    using (var ms = new MemoryStream())
    {
        using (var compress = new GZipStream (ms, CompressionMode.Compress))
        {
            compress.Write(raw, 0, raw.Length);
            compress.Close();

            return ms.ToArray();
        }
    } 
}

What happened was that the data seemed to get saved in a bad state that required two calls to ReadToEnd() in the decompression routine later on to extract the same data. Very odd!