Почему сжатый, а затем несжатый поток разной длины

Я использую библиотеку SevenZipSharp для сжатия, а затем распаковки MemoryStream, который содержит простой сериализованный объект. Однако сжатый и распакованный потоки имеют разную длину.

Из приведенного ниже кода я получаю

Длина ввода: 174 Длина вывода: 338

(dll SevenZipSharp включен в качестве ссылки, а 7z.dll включен в выходные данные проекта)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace DataTransmission {
class Program {
    static void Main(string[] args)
    {

        SevenZip.SevenZipCompressor compressor = new SevenZip.SevenZipCompressor();
        //compressor.CompressionMethod = SevenZip.CompressionMethod.Lzma2;
        //compressor.CompressionLevel = SevenZip.CompressionLevel.Normal;

        MemoryStream inputStream = new MemoryStream();

        Person me = new Person("John", "Smith");
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(inputStream, me);

        Int32 inputStreamLength = (Int32)inputStream.Length;

        MemoryStream outputStream = new MemoryStream();

        compressor.CompressStream(inputStream, outputStream);
        SevenZip.SevenZipExtractor decompressor = new SevenZip.SevenZipExtractor(outputStream);
        decompressor.ExtractFile(0, outputStream);
        Int32 outputStreamLength = (Int32)outputStream.Length;


        Console.WriteLine("Input length: {0}", inputStreamLength);
        Console.WriteLine("Output length: {0}", outputStreamLength);

        Console.ReadLine();
    }
}

[Serializable]
public class Person {
    public string firstName;
    public string lastName;

    public Person(string fname, string lname) {
        firstName = fname;
        lastName = lname;
    }
}

}

Может ли кто-нибудь помочь мне с тем, почему это может быть?

Спасибо,


person ChrisAU    schedule 12.05.2011    source источник
comment
Используйте отдельный поток для сжатых и распакованных данных. Ваш outputStream, вероятно, содержит Compressed + Decompressed.   -  person Henk Holterman    schedule 12.05.2011


Ответы (2)


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

(На самом деле это очень странно, потому что декомпрессор читает из outputStream, а также записывает в outputStream. Плохая идея. Используйте два разных потока.)

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

inputStream.Position = 0;

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


Я только что внес следующее изменение в ваш код, после чего я получаю одинаковую длину для ввода и вывода:

MemoryStream targetStream = new MemoryStream();
decompressor.ExtractFile(0, targetStream);
Int32 outputStreamLength = (Int32)targetStream.Length;

Как я уже сказал, вы также должны внести соответствующие другие изменения.

person Jon Skeet    schedule 12.05.2011
comment
большой! спасибо за помощь, ваша поправка была на самом деле проблемой, и теперь я внесу другие изменения, как вы предложили. Еще раз спасибо за отличный своевременный ответ! - person ChrisAU; 12.05.2011

Однако сжатый и распакованный потоки имеют разную длину.

В этом вся цель компрессии...


Посмотрите на этот кусок кода:

  SevenZip.SevenZipExtractor decompressor = 
       new SevenZip.SevenZipExtractor(outputStream);
  decompressor.ExtractFile(0, outputStream);

Вы распаковываете из outputStream в outputStream. Это, вероятно, не удастся с большими данными. Внесите изменения, чтобы он читался

  SevenZip.SevenZipExtractor decompressor = 
      new SevenZip.SevenZipExtractor(compressedStream);
  decompressor.ExtractFile(0, outputStream);
person Henk Holterman    schedule 12.05.2011
comment
Когда вы посмотрите на его код, должно быть ясно, что он имеет в виду. Кроме того, в заголовке вопроса также говорится, что проблема заключается в original -> compress -> uncompress -> new с разной длиной original и new. - person Daniel Hilgarth; 12.05.2011
comment
@Daniel: Да, я отреагировал на начальный абзац. - person Henk Holterman; 12.05.2011