Проблема при упаковке потока с помощью GZipStream - на выходе получается пустой поток

Рейтинг: 1Ответов: 1Опубликовано: 27.02.2015

Добрый день. Код считывает файлы с диска, упаковывает их и пишет в блоб-поле в БД.

Некоторые файлы проходят без проблем, а на некоторых наблюдается следующее: после упаковки размер стрима равен 10 байт (хотя источник например 11 килобайт). При попытке распаковать такой стрим он распаковывается в нулевой (длина равна нулю), никаких исключений не возникает.

код упаковки:

    public void CompressFrom(Stream src) // src.Lenth == 11900
    {
        using (var ms = new MemoryStream())
        using (var gz = new GZipStream(ms, CompressionMode.Compress, false))
        {
            src.Position = 0;
            src.CopyTo(gz);
            Data = ms.ToArray(); // ms.Length == 10 ! WTF?!
        }
    }

На входе FileStream. И при этом часть файлов запаковывается совершенно нормально, а другая часть - вот так. Выручайте, сломал всю голову уже )

Ответы

▲ 3Принят

Вы делаете немного неправильно. Надо так:

public void CompressFrom(Stream src) // src.Lenth == 11900
{
    using (var ms = new MemoryStream())
    {
        // кажется, нужно поменять false на true
        using (var gz = new GZipStream(ms, CompressionMode.Compress, true))
        {
            src.Position = 0;
            src.CopyTo(gz);
        }
        Data = ms.ToArray();
    }
}

Объяснение: GZipStream иногда откладывает фактическую запись до того момента, который считает удобным, а до этого просто накапливает данные. (Не исключено, что с новыми данными он захочет паковать уже имеющиеся данные по-другому, поэтому такая стратегия оправдана.) Когда вы закрываете GZipStream (а это происходит по выходу из блока), он больше не имеет права откладывать фактическую запись, а значит, данные попадают в целевой MemoryStream.