Проблема сжатия GZipStream (потерянный байт) - PullRequest
9 голосов
/ 13 июня 2011

У меня странная проблема с GZip Serializer.

Попытка сериализации объекта с данными в нем.

Следующий код дает результаты ( в POINT1 при отладке ): ms.Length = 100028 и uncompressedStream.Length = 100027

После POINT1 возникает исключениедо того, как анализ был завершен. ", который я думаю, является результатом этого потерянного байта.

Я использую .net 4.0.

        //generating data
        int length = 100000;
        byte[] data = new byte[length];
        for (int i = 0; i < length; i++)
        {
            data[i] = System.Convert.ToByte(i % 100 + i % 50);
        }


        //serialization into memory stream
        IFormatter formatter = new BinaryFormatter();
        var ms = new MemoryStream();
        formatter.Serialize(ms, data);
        ms.Seek(0, SeekOrigin.Begin);

        //GZip zip
        MemoryStream compressedStream = new MemoryStream();
        var Compress = new GZipStream(compressedStream, CompressionMode.Compress);
        ms.CopyTo(Compress);  
        compressedStream.Seek(0, SeekOrigin.Begin);

        //GZip Unzip
        MemoryStream uncompressedStream = new MemoryStream();
        var Decompress = new GZipStream(compressedStream, CompressionMode.Decompress);
        Decompress.CopyTo(uncompressedStream);
        uncompressedStream.Seek(0, SeekOrigin.Begin);

        //deserialization from memory stream
        //POINT1
        var oo = formatter.Deserialize(uncompressedStream);
        var o = (byte[])oo;

        //checking
        Assert.AreEqual(data.Length, o.Length);
        for (int i = 0; i < data.Length; i++)
            Assert.AreEqual(data[i], o[i]);

1 Ответ

14 голосов
/ 13 июня 2011

Сжатые потоки не сбрасываются (и не могут должным образом сбрасываться), пока не будут закрыты.Вам нужно будет закрыть GZipStream.Указание не закрывать основной поток (один из аргументов конструктора) облегчит это.

        //generating data
        int length = 100000;
        byte[] data = new byte[length];
        for (int i = 0; i < length; i++)
        {
            data[i] = System.Convert.ToByte(i % 100 + i % 50);
        }

        byte[] o;
        //serialization into memory stream
        IFormatter formatter = new BinaryFormatter();
        using (var ms = new MemoryStream())
        {
            formatter.Serialize(ms, data);
            ms.Seek(0, SeekOrigin.Begin);

            //GZip zip
            using(MemoryStream compressedStream = new MemoryStream())
            {
                using (var Compress = new GZipStream(compressedStream, CompressionMode.Compress, true))
                {
                    ms.CopyTo(Compress);
                }
                compressedStream.Seek(0, SeekOrigin.Begin);
                //GZip Unzip
                using (MemoryStream uncompressedStream = new MemoryStream())
                {
                    using (var Decompress = new GZipStream(compressedStream, CompressionMode.Decompress, true))
                    {
                        Decompress.CopyTo(uncompressedStream);
                    }
                    uncompressedStream.Seek(0, SeekOrigin.Begin);
                    var oo = formatter.Deserialize(uncompressedStream);
                    o = (byte[])oo;
                }
            }
            //deserialization from memory stream
            //POINT1

        }
        //checking
        Debug.Assert(data.Length == o.Length);
        for (int i = 0; i < data.Length; i++)
            Debug.Assert(data[i] == o[i]);
...