Загадочная проблема .Net C# DeflateStream

Интересно, может ли кто-нибудь пролить свет на проблему, которая сводит меня с ума:

Я пишу тестовый класс сжатия и декомпрессии. Чтобы проверить это, я сериализую набор данных в поток памяти, сжимаю и распаковываю его и сравниваю результаты.

Со сжатием все в порядке, но с разжатием дело обстоит иначе. Это функция распаковки:

    public static Stream GetUncompressedStreamCopy(Stream inStream)
    {
      Stream outStream = new MemoryStream();

      inStream.Position = 0;

      DeflateStream uncompressStream = new DeflateStream(inStream, 
        CompressionMode.Decompress, true);

      byte[] buffer = new byte[65536];

      int totalread = 0;
      int bytesread = 0;


      do {
        bytesread = uncompressStream.Read(buffer, 0, buffer.Length);
        totalread += bytesread;
        outStream.Write(buffer, 0, bytesread);
        Console.WriteLine("bytesRead: [{0}]\t outStream.Length [{1}]",
        bytesread, outStream.Length);
      } while (bytesread > 0);


      Console.WriteLine("total bytes read [{0}]", totalread);
      outStream.Flush();
      return outStream;
}

При размере буфера 65536 распакованный поток всегда возвращает на один байт меньше, чем в несжатом виде.

Теперь это подводит меня ко второй проблеме, с которой я борюсь. При некоторых размерах буфера функция uncompressStream.Read возвращает 0, даже если для извлечения еще остались сжатые данные.

В этих случаях deflateStream.Read(s) только один раз в цикле do{}, а затем возвращает несжатый поток, равный размеру буфера, если вы увеличите размер буфера на один байт, все будет хорошо (за исключением отсутствующего байта).

Вывод для размера буфера 65536: (исходные несжатые данные 207833)

bytesRead: [65536]       outStream.Length [65536]
bytesRead: [65536]       outStream.Length [131072]
bytesRead: [58472]       outStream.Length [189544]
bytesRead: [18288]       outStream.Length [207832]
bytesRead: [0]           outStream.Length [207832]
total bytes read [207832]

размер буфера 189544 (какое-то магическое число, где код танков)

bytesRead: [189544]      outStream.Length [189544]
bytesRead: [0]           outStream.Length [189544]
total bytes read [189544]
Unompressed stream size 189544

Также обратите внимание на 3-е чтение размера буфера 65536 ex: bytesRead: [58472] Ясно, что это также должно быть 65536, так как в буфере еще остались данные?

Любые идеи будут очень оценены.

Тиа

  • Жако

person twiga    schedule 22.10.2009    source источник
comment
Как вы можете говорить, что сжатие в порядке, если вы не можете распаковать данные?   -  person Lasse V. Karlsen    schedule 22.10.2009
comment
Привет, Лассе, я написал еще одну реализацию, в которой сжатый размер одного и того же набора данных равен размеру сжатого потока после сжатия. - надеюсь, что это имеет смысл   -  person twiga    schedule 22.10.2009


Ответы (3)


Вы всегда должны вызывать Close() для потоков сжатия. Обратите внимание, что Flush() недостаточно. Подозреваю, что из-за этого в потоке deflate отсутствуют данные.

person liggett78    schedule 22.10.2009
comment
Поначалу Close не работал, потому что он также закрывал базовый поток. Но вызов .Close() после того, как поток deflate был создан с опцией true для leaveOpen, я мог закрыть его, и базовый поток был передан обратно вызывающей стороне! тывм! - person twiga; 22.10.2009
comment
DeflateStream — это поток, что означает, что он IDisposable. Вам нужно предложение использования. Хотя Close() может быть достаточно, вы нарушили модель использования, не вызвав Dispose() или заключив ее в предложение using. - person Cheeso; 23.10.2009

Мои экстрасенсорные способности говорят мне, что на самом деле у вас есть работающая реализация декомпрессии, но вы забыли перед этим очистить поток сжатия.

person SoftMemes    schedule 22.10.2009
comment
DeflateStream.Close() исправил это tyvm - person twiga; 22.10.2009
comment
Можете ли вы опубликовать пример кода, где разместить Close и распаковать? Чтение из потока deflate всегда не дает мне данных. Но данные должны быть в порядке. Хотя может проблема в другом.. - person Liam Mitchell; 08.12.2018