Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inflate a file with zlib.NET?

I'm using the zlib.NET library to try and inflate files that are compressed by zlib (on a Linux box, perhaps). Here's what I'm doing:

zlib.ZInputStream zinput =
    new zlib.ZInputStream(File.Open(path, FileMode.Open, FileAccess.Read));

while (stopByte != (data = zinput.ReadByte()))
{
  // check data here
}

zinput.Close();

The data bytes match the compressed data bytes, so I must be doing something wrong.

like image 642
Ben Collins Avatar asked Oct 09 '08 02:10

Ben Collins


People also ask

What is zlib inflate?

The zlib. inflate() method is an inbuilt application programming interface of the Zlib module which is used to decompress a chunk of data. Syntax: zlib.inflate( buffer, options, callback )

How do you use zlib compression?

For zlib compression (referred to as deflate as you "take out all the air of your data") you allocate z_stream structure, call deflateInit() and then: fill next_in with the next chunk of data you want to compress. set avail_in to the number of bytes available in next_in.

Does gzip use zlib?

zlib was adapted from the gzip code. All of the mentioned patents have since expired. The zlib library supports Deflate compression and decompression, and three kinds of wrapping around the deflate streams.


3 Answers

Other than failing to use a "using" statement to close the stream even in the face of an exception, that looks okay to me. Is the data definitely compressed? Are you able to decompress it with zlib on the linux box?

Having looked at the source code, it's pretty ghastly - a call to int Read(buffer, offset, length) will end up calling its internal int Read() method length times for example. Given that sort of shaky start, I'm not sure I'd trust the code particularly heavily, but I'd have expected it to work at least slightly! Have you tried using SharpZipLib?

like image 109
Jon Skeet Avatar answered Oct 24 '22 06:10

Jon Skeet


It appears I made the mistake of assuming all virtual methods were overridden, which wasn't the case. I was using zlib.ZInputStream.ReadByte(), which is just the inherited Stream.ReadByte(), which doesn't do any inflate.

I used zlib.ZInputStream.Read() instead, and it worked like it should.

like image 7
Ben Collins Avatar answered Oct 24 '22 06:10

Ben Collins


Skipping the zlib header (first two bytes, 78 9C) and then using the DeflateStream built into .net worked for me.

using(var input = File.OpenRead(...))
using(var output = File.Create(...))
{
    // if there are additional headers before the zlib header, you can skip them:
    // input.Seek(xxx, SeekOrigin.Current);

    if (input.ReadByte() != 0x78 || input.ReadByte() != 0x9C)//zlib header
        throw new Exception("Incorrect zlib header");

    using (var deflateStream = new DeflateStream(decryptedData, CompressionMode.Decompress, true))
    {
        deflateStream.CopyTo(output);
    }
}
like image 4
CodesInChaos Avatar answered Oct 24 '22 04:10

CodesInChaos