GZipStream decompression not working

7

7elephants

I have written a class to do compression/decompression using
System.IO.Compression.GZipStream. The compression seems to work fine,
but when I try and decompress a compressed string, nothing is returned
in the buffer...To do the processing, I pass the GZipStream as input
into the following function:

private void ProcessStreams(Stream input, Stream output) {
int offset = 0;

try {
if (input.CanRead & output.CanWrite) {
byte[] buffer = new byte[4096];

//make sure stream is at the beginning
if (input.CanSeek)
input.Seek(0,SeekOrigin.Begin);

while (true) {
//read input stream
int bytesRead = input.Read(buffer, 0,
bufferSize);

if (bytesRead > 0)
{
//write to output stream
output.Write(buffer, offset, bytesRead);
offset += bytesRead;
} else {
break;
}
}

//flush write buffer
output.Flush();
}
} catch (ArgumentNullException argEx) {
throw new CompressorException("Input stream is not
valid", ExceptionLevel.Error, false, this.ToString(),
"GetCompressionOutput",
argEx);
} catch (InvalidOperationException ioEx) {
throw new CompressorException("Input stream is
read-only", ExceptionLevel.Error, false, this.ToString(),
"GetCompressionOutput",
ioEx);
} catch (IOException ioEx) {
throw new CompressorException("Invalid I/O operation",
ExceptionLevel.Error, false, this.ToString(),
"GetCompressionOutput",
ioEx);
} catch (Exception ex) {
throw new CompressorException("Unspecified exception",
ExceptionLevel.Error, false, this.ToString(),
"GetCompressionOutput",
ex);
}

+------------------------------------------------------------------------+
I have read in doing research that the GZipStream doesn't return the
bytes read when running GZipStream.Read (is this true?), so when I
check the buffer, it is "empty". The base stream of the GZipStream is
a MemoryStream if that makes a difference.

Any help would be great. Thanks in advance.
 
G

Gabriele G. Ponti

I remember having a similar problem some months ago. In my case the culprit
was the compression part.

I have attached the class I wrote when I was testing the GZipStream class.
It's not production quality, so you want to use it only as reference. Also
be advised that in my example I use a header with the size of the
uncompressed data.

HTH,

Gabriele
 
7

7elephants

I am trying to decompress a stream via the GZipStream (GZip, not ZIP
algorithm) class...

As far as I know, that is all I need to do it...no other libraries
necessary.
What are you attempting to acutally do? If it's reading and writing zip
files, import java.util.zip. You'll need a reference to "vjslib.dll" to use
it. A C# Zip example is at
http://msdn.microsoft.com/msdnmag/issues/03/06/ZipCompression/#S8

I use this library in a production application for our sales force.

Mike Ober.

7elephants said:
I have written a class to do compression/decompression using
System.IO.Compression.GZipStream. The compression seems to work fine,
but when I try and decompress a compressed string, nothing is returned
in the buffer...To do the processing, I pass the GZipStream as input
into the following function:

private void ProcessStreams(Stream input, Stream output) {
int offset = 0;

try {
if (input.CanRead & output.CanWrite) {
byte[] buffer = new byte[4096];

//make sure stream is at the beginning
if (input.CanSeek)
input.Seek(0,SeekOrigin.Begin);

while (true) {
//read input stream
int bytesRead = input.Read(buffer, 0,
bufferSize);

if (bytesRead > 0)
{
//write to output stream
output.Write(buffer, offset, bytesRead);
offset += bytesRead;
} else {
break;
}
}

//flush write buffer
output.Flush();
}
} catch (ArgumentNullException argEx) {
throw new CompressorException("Input stream is not
valid", ExceptionLevel.Error, false, this.ToString(),
"GetCompressionOutput",
argEx);
} catch (InvalidOperationException ioEx) {
throw new CompressorException("Input stream is
read-only", ExceptionLevel.Error, false, this.ToString(),
"GetCompressionOutput",
ioEx);
} catch (IOException ioEx) {
throw new CompressorException("Invalid I/O operation",
ExceptionLevel.Error, false, this.ToString(),
"GetCompressionOutput",
ioEx);
} catch (Exception ex) {
throw new CompressorException("Unspecified exception",
ExceptionLevel.Error, false, this.ToString(),
"GetCompressionOutput",
ex);
}

+------------------------------------------------------------------------+
I have read in doing research that the GZipStream doesn't return the
bytes read when running GZipStream.Read (is this true?), so when I
check the buffer, it is "empty". The base stream of the GZipStream is
a MemoryStream if that makes a difference.

Any help would be great. Thanks in advance.
 
J

Jon Skeet [C# MVP]

7elephants said:
I have written a class to do compression/decompression using
System.IO.Compression.GZipStream. The compression seems to work fine,
but when I try and decompress a compressed string, nothing is returned
in the buffer...To do the processing, I pass the GZipStream as input
into the following function:

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
7

7elephants

Here is the method that does the compression/decompression...

private void ProcessStreams(Stream input, Stream output) {
int offset = 0;

try {
if (input.CanRead & output.CanWrite) {
Int32 bufferSize = 100;

Int32.TryParse(ConfigurationManager.AppSettings["bufferLimit"].ToString(),
out bufferSize);

byte[] buffer = new byte[bufferSize];

//make sure stream is at the beginning
if (input.CanSeek)
input.Seek(0,SeekOrigin.Begin);

while (true) {
//read input stream
int bytesRead = input.Read(buffer, 0,
bufferSize);

if ((bytesRead > 0) || (buffer[0] > 0))
{
//write to output stream
output.Write(buffer, offset, bytesRead);
offset += bytesRead;

//force new buffer
buffer = new byte[bufferSize];
} else {
break;
}
}

//flush write buffer
output.Flush();
}
} catch (ArgumentNullException argEx) {
throw new CompressorException("Input stream is not
valid", ExceptionLevel.Error, false, this.ToString(),
"GetCompressionOutput",
argEx);
} catch (InvalidOperationException ioEx) {
throw new CompressorException("Input stream is
read-only", ExceptionLevel.Error, false, this.ToString(),
"GetCompressionOutput",
ioEx);
} catch (IOException ioEx) {
throw new CompressorException("Invalid I/O operation",
ExceptionLevel.Error, false, this.ToString(),
"GetCompressionOutput",
ioEx);
} catch (Exception ex) {
throw new CompressorException("Unspecified exception",
ExceptionLevel.Error, false, this.ToString(),
"GetCompressionOutput",
ex);
}



+==========================================+

Here is the specific code that calls the method above...

....
GZipStream compressedStream = new GZipStream(inputStream,
CompressionMode.Decompress, true);

ProcessStreams(compressedStream, outputStream);
+==========================================+

When I change the base stream from a MemoryStream to a FileStream, the
decompression seems to work. I have seen information about
MemoryStreams and GZipStream not playing nice, but I haven't seen any
specifics.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top