Question

I'm using the SevenZipSharp library to compress and then uncompress a MemoryStream which contains a simple serialized object. However, the compressed and decompressed streams are of different length.

From the code run below I get

Input length: 174 Output length: 338

(the SevenZipSharp dll is included as a reference and the 7z.dll is included in the project output)

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;
    }
}

}

Can anyone help me with why this may be?

Thanks,

Was it helpful?

Solution

You've decompressed into outputStream despite that already containing data. You should use a new MemoryStream for the output.

(In fact, it's very odd because the decompressor is reading from outputStream and also writing to outputStream. Bad idea. Use two different streams.)

You should also rewind each stream after you've written to it and before something else wants to read it, e.g. with

inputStream.Position = 0;

It's possible that SevenZipLib is doing that for you in this case, but in general if you want something to act from the start of the stream, you should reset it appropriately.


I've just made the following change to your code, at which point I get the same length for input and output:

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

As I say, you should make the appropriate other changes too.

OTHER TIPS

However, the compressed and decompressed streams are of different length

That is the whole purpose of compression ...


Look at this piece of the code:

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

You are decompressing from outputStream to outputStream. It will probably fail with larger data. Make changes so that it reads

  SevenZip.SevenZipExtractor decompressor = 
      new SevenZip.SevenZipExtractor(compressedStream);
  decompressor.ExtractFile(0, outputStream);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top