This project is read-only.

Compress / Decompress String

Aug 16, 2010 at 12:50 AM
Hello there, I am trying to find a way to compress / decompress a string in memory using the SevenZipSharp library. In other words, no writing to files. Does anyone have an example on how to do this?
Aug 17, 2010 at 12:20 AM
Edited Aug 17, 2010 at 12:25 AM
So here is what I've got so far
public string Compress(string input)
{
	byte[] inputbuffer = Encoding.UTF8.GetBytes(input);
	byte[] compressed = null;
	SevenZipCompressor compressor = new SevenZipCompressor();
	compressor.CompressionMethod = CompressionMethod.Ppmd;
	compressor.CompressionLevel = CompressionLevel.Ultra;
	compressor.ScanOnlyWritable = true;
	using (MemoryStream msin = GetUTF8MemorySteam(input))
	{
		using (MemoryStream msout = new MemoryStream())
		{
			compressor.CompressStream(msin, msout);
			compressed = new byte[msout.Length];
			msout.Read(compressed, 0, compressed.Length);
		}
	}
	byte[] compressedbuffer = new byte[compressed.Length + 4];
	Buffer.BlockCopy(compressed, 0, compressedbuffer, 4, compressed.Length);
	Buffer.BlockCopy(BitConverter.GetBytes(inputbuffer.Length), 0, compressedbuffer, 0, 4);
	return Convert.ToBase64String(compressedbuffer);
}
 
public string Decompress(string input)
{
	byte[] inputbuffer = Convert.FromBase64String(input);
	byte[] uncompressedbuffer = null;
	using (MemoryStream msin = new MemoryStream())
	{
		int msgLength = BitConverter.ToInt32(inputbuffer, 0);
		msin.Write(inputbuffer, 4, inputbuffer.Length - 4);
		uncompressedbuffer = new byte[msgLength];
		msin.Position = 0;
		using (SevenZipExtractor extractor = new SevenZipExtractor(msin))
		{
			using (MemoryStream msout = new MemoryStream())
			{
				extractor.ExtractFile(0, msout);
				uncompressedbuffer = new byte[msout.Length];
				msout.Read(uncompressedbuffer, 0, uncompressedbuffer.Length);
			}
		}
	}
	return Encoding.UTF8.GetString(uncompressedbuffer);
}
All looks good except that the "SevenZipExtractor" constructor throws an ArgumentException exception when called: "The stream is invalid or no corresponding signature was found.".
Can anyone share insight on what could be causing a "signature" error?
Jan 3, 2012 at 3:27 PM

I've had this same error. I haven't been able to find a way around having to use a temporary file.

 

The odd thing is that the data compresses properly, and I can dump it to a file and open with 7zip or WinRAR and the extracted contents are a binary match to the original data. The extractor just does not see it as a valid stream.

Aug 11, 2012 at 4:50 PM

Thx, the original snippet was good for me. I changed for my necessities.

Found out how to resolve:

The "SevenZipExtractor" constructor throws an ArgumentException exception when called: "The stream is invalid or no corresponding signature was found."

Problem:

		msin.Write(inputbuffer, 4, inputbuffer.Length - 4);

instead:

	using (MemoryStream msin = new MemoryStream())

use:

	using (MemoryStream msin = new MemoryStream(inputbuffer))
Aug 11, 2012 at 5:13 PM
Edited Aug 11, 2012 at 5:14 PM

I wrote a version what compression rate not ruined with Convert.ToBase64String() and good for store very long text or RTF text into SQL Server ntext field:

 

	public static string CompressString(string text)
	{
		byte[] compressedData = null;

		SevenZipCompressor compressor = new SevenZipCompressor();
		compressor.CompressionMethod = CompressionMethod.Ppmd;
		compressor.CompressionLevel = CompressionLevel.Ultra;
		compressor.ScanOnlyWritable = true;
		compressor.DefaultItemName = "T";

		using (MemoryStream msin = new MemoryStream(Encoding.GetUTF8.GetBytes(text)))
		{
			using (MemoryStream msout = new MemoryStream())
			{
				compressor.CompressStream(msin, msout);

				compressedData = msout.ToArray();
			}
		}
		return Encoding.GetEncoding(1251).GetString(compressedData);
	}

	
	public static string DecompressString(string compressedText)
	{
		byte[] uncompressedbuffer = null;

		using (MemoryStream compressedbuffer = new MemoryStream(Encoding.GetEncoding(1251).GetBytes(compressedText)))
		{
			try
			{
				using (SevenZipExtractor extractor = new SevenZipExtractor(compressedbuffer))
				{
					using (MemoryStream msout = new MemoryStream())
					{
						extractor.ExtractFile(0, msout);
						uncompressedbuffer = msout.ToArray();
					}
				}
			}
			catch (Exception e)
			{
				uncompressedbuffer = Encoding.UTF8.GetBytes(e.Message);
			}
		}
		return Encoding.UTF8.GetString(uncompressedbuffer);
	}

 

Do not forget:

1. using SevenZip;

2. like this: SevenZip.SevenZipBase.SetLibraryPath(@"C:\Program Files\7z.dll");

3. reference to: SevenZipSharp