Программное сжатие / распаковка в MemoryStream с помощью GZipStream - PullRequest
4 голосов
/ 15 июня 2011

Я создал (на основе статьи CodeProject) класс-оболочку (C #) для использования GZipStream для сжатия MemoryStream.Хорошо сжимается, но не распаковывается.Я просмотрел много других примеров, в которых есть та же проблема, и я чувствую, что следую тому, что было сказано, но все равно ничего не получаю, когда декомпрессирую.Вот методы сжатия и распаковки:

public static byte[] Compress(byte[] bSource)
{

    using (MemoryStream ms = new MemoryStream())
    {
        using (GZipStream gzip = new GZipStream(ms, CompressionMode.Compress, true))
        {
            gzip.Write(bSource, 0, bSource.Length);
            gzip.Close();
        }

        return ms.ToArray();
    }
}


public static byte[] Decompress(byte[] bSource)
{

    try
    {
        using (MemoryStream ms = new MemoryStream())
        {
            using (GZipStream gzip = new GZipStream(ms, CompressionMode.Decompress, true))
            {
                gzip.Read(bSource, 0, bSource.Length);
                gzip.Close();
            }

            return ms.ToArray();
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Error decompressing byte array", ex);
    }
}

Вот пример того, как я его использую:

string sCompressed = Convert.ToBase64String(CompressionHelper.Compress("Some Text"));
// Other Processes
byte[] bReturned = CompressionHelper.Decompress(Convert.FromBase64String(sCompressed));
// bReturned has no elements after this line is executed

Ответы [ 2 ]

7 голосов
/ 15 июня 2011

В методе распаковки есть ошибка.

Код не читает содержимое bSource.Напротив, он переопределяет чтение содержимого из пустого gzip, созданного на основе пустого потока памяти.

В основном то, что делает ваша версия кода:

//create empty memory
using (MemoryStream ms = new MemoryStream())

//create gzip stream over empty memory stream
using (GZipStream gzip = new GZipStream(ms, CompressionMode.Compress, true))

// write from empty stream to bSource
gzip.Write(bSource, 0, bSource.Length);

Исправление может выглядетьэто:

public static byte[] Decompress(byte[] bSource)
{
    using (var inStream = new MemoryStream(bSource))
    using (var gzip = new GZipStream(inStream, CompressionMode.Decompress))
    using (var outStream = new MemoryStream())
    {
        gzip.CopyTo(outStream);
        return outStream.ToArray();
    }
}
1 голос
/ 03 февраля 2015

ОП сказал в редактировании, теперь откат:

Благодаря объяснению Алекса о том, что происходит не так, я смог исправить метод Декомпрессии. К сожалению, я использую .Net 3.5, поэтому я не смог реализовать метод Stream.CopyTo, который он предложил. Однако с его объяснением я смог найти решение. Я внес соответствующие изменения в метод декомпрессии ниже.

    public static byte[] Decompress(byte[] bSource)
    {
        try
        {
            using (var instream = new MemoryStream(bSource))
            {
                using (var gzip = new GZipStream(instream, CompressionMode.Decompress))
                {
                    using (var outstream = new MemoryStream())
                    {
                        byte[] buffer = new byte[4096];

                        while (true)
                        {
                            int delta = gzip.Read(buffer, 0, buffer.Length);

                            if (delta > 0)
                                outstream.Write(buffer, 0, delta);

                            if (delta < 4096)
                                break;
                        }
                        return outstream.ToArray();
                    }
                }
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error decompressing byte array", ex);
        }
    }
...