Load File Not working - The magic number in GZip header is not correct

Anthony Nichols picture Anthony Nichols · Jan 7, 2013 · Viewed 15.4k times · Source

I am attempting to create a Save/Load class that has the option for saving & load files compressed files. Below is what I have so far. Stepping through it seems to work just fine, except that I get a "The magic number in GZip header is not correct" exception. I don't understand how this can be as I am checking to make sure that the number is there before I pass it over, and I have verified via an external program that it is a GZip file.

Any assistance in finding out where I went wrong would be appreciated. Constructive criticism of my code is always welcome - Thanks!

public static class SaveLoad
{
    public static void Save(string fileName, object savefrom, bool compress)
    {
        FileStream stream = new FileStream(fileName, FileMode.Create);

        BinaryFormatter formatter = new BinaryFormatter();
        if (compress)
        {
            GZipStream compressor = new GZipStream(stream, CompressionMode.Compress);
            formatter.Serialize(compressor, savefrom);
            compressor.Close();
        }
        else { formatter.Serialize(stream, savefrom); }

        stream.Close();
    }

    public static object Load(string fileName)
    {
        object loadedObject = null;

        try
        {
            FileStream stream = new FileStream(fileName, FileMode.Open);

            BinaryFormatter formatter = new BinaryFormatter();

            if (stream.Length > 4)
            {
                byte[] data = new byte[4];
                stream.Read(data, 0, 4);

                if (BitConverter.ToUInt16(data, 0) == 0x8b1f) //GZIP_LEAD_BYTES == 0x8b1f
                {
                    GZipStream decompressor = new GZipStream(stream, CompressionMode.Decompress);
                    loadedObject = formatter.Deserialize(decompressor); //Exception
                    decompressor.Close();
                }
                else { loadedObject = formatter.Deserialize(stream); }
            }
            stream.Close();
        }
        catch (Exception e)
        {
            Logger.StaticLog.AddEvent(new Logger.lEvent(null, Logger.lEvent.EventTypes.Warning, "Failed to load file: " + fileName, e)
            {
                SendingObject = "SaveLoad"
            });
            Logger.StaticLog.WriteLog();
            throw;
        }

        return loadedObject;
    }
}

Answer

Anton Kovalenko picture Anton Kovalenko · Jan 7, 2013

It seems that you read the magic number before passing the stream to decompressor (which won't read the magic number then, because you've already read it).

Use stream.Seek(0,SeekOrigin.Begin) before you decompress.