Как преобразовать сжатый поток в несжатый поток в С# с помощью GZipStream

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

...
using (MemoryStream compressedStream = new MemoryStream()) {
    ...some code that builds the compressedStream for an undetermined
    number of byteArrays from a database
    using (MemoryStream uncompressedStream = new MemoryStream()) {
        // method 1
        using (GZipStream unzippedStream = new GZipStream(compressedStream, CompressionMode.Decompress)) {
            unzippedStream.CopyTo(uncompressedStream);
        }
        // method 2
        using (GZipStream unzippedStream = new GZipStream(uncompressedStream, CompressionMode.Decompress)) {
            compressedStream.CopyTo(unzippedStream);
        }
        ... do something with uncompressedStream
    }
}

Метод 1 соответствует примерам, которые я вижу здесь, но вызывает ошибку «поток не поддерживает запись».

Метод 2 имеет больше смысла, но несжатый поток всегда пуст.

P.S. На самом деле то, что я хотел бы иметь, это что-то простое, например

MemoryStream compressed = GZipStream(uncompressed, Compress)
MemoryStream upcompressed = GZipStream(compressed, Decompress)

person nuander    schedule 25.07.2016    source источник
comment
Пишите, чтобы сжимать, читайте, чтобы распаковывать.   -  person Bryce Wagner    schedule 26.07.2016
comment
В обоих случаях базовый поток для GZipStream содержит сжатые данные.   -  person Bryce Wagner    schedule 26.07.2016
comment
Ваш первый метод должен работать. Вы уверены, что используемый вами массив байтов является исходным сжатым? Вы не можете просто собрать сжатые массивы байтов вместе и ожидать, что они будут декомпилированы, как вы знаете.   -  person Visual Vincent    schedule 26.07.2016
comment
Без хорошего минимально воспроизводимого примера невозможно точно знать, что вы сделали не так. Краткая версия того, как это сделать: создайте MemoryStream из вашего byte[], передайте этот поток в GZipStream, а затем прочитайте из GZipStream.   -  person Peter Duniho    schedule 26.07.2016
comment
Связанный: stackoverflow.com/questions/3722192/   -  person    schedule 26.07.2016
comment
@Bruce - я прямо не говорю ему что-либо писать, но в какой-то момент распакованный поток должен быть где-то записан, чтобы быть полезным. Можете ли вы уточнить, пожалуйста?   -  person nuander    schedule 26.07.2016
comment
@Visual — сжатые данные были преобразованы в байты и разбиты на куски. Я собираю куски в сжатый поток   -  person nuander    schedule 26.07.2016
comment
Хорошо, тогда, если у вас есть это в правильном порядке, ваш первый метод не должен быть проблемой.   -  person Visual Vincent    schedule 26.07.2016
comment
Да, теперь это работает, как только я установил позицию сжатого потока на 0. Я прикреплю пример рабочего кода.   -  person nuander    schedule 26.07.2016


Ответы (1)


Этот пример кода работает. Первая часть — просто получить сжатый массив байтов. Вторая часть демонстрирует, как сжатый поток может быть создан в коде, запись может выполняться несколько раз. Но позиция должна быть установлена ​​на 0.

byte[] compressed;
string output;

using (var outStream = new MemoryStream()) {
    using (var tinyStream = new GZipStream(outStream, CompressionMode.Compress))
    using (var mStream = new MemoryStream(Encoding.UTF8.GetBytes("This is a test"))) {
        mStream.CopyTo(tinyStream);
    }
    compressed = outStream.ToArray();
}

using (var compressedStream = new MemoryStream()) {
    // can do multiple writes here to create the compressed stream
    compressedStream.Write(compressed, 0, compressed.Length);
    compressedStream.Flush();
    compressedStream.Position = 0;
    using (var unzippedStream = new GZipStream(compressedStream, CompressionMode.Decompress))
    using (var uncompressedStream = new MemoryStream()) {
        unzippedStream.CopyTo(uncompressedStream);
        output = Encoding.UTF8.GetString(uncompressedStream.ToArray());
    }
}

Console.WriteLine(output);
person nuander    schedule 26.07.2016