Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StreamReader ReadToEnd() returns empty string on first attempt

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

like image 236
Victor Cassel Avatar asked Dec 16 '10 13:12

Victor Cassel


2 Answers

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!

like image 131
Victor Cassel Avatar answered Oct 15 '22 03:10

Victor Cassel


try adding ms.Position = 0 before string ret = sr.ReadToEnd();

like image 43
Adam Avatar answered Oct 15 '22 03:10

Adam