DarkAtom
DarkAtom

Reputation: 3171

C# equivalent to zlib.decompress

What is the equivalent of the Python function zlib.decompress() in C#? I need to decompress some zlib files using C# and I don't know how to do it.

Python example:

import zlib

file = open("myfile", mode = "rb")
data = zlib.decompress(file.read())
uncompressed_output = open("output_file", mode = "wb")
uncompressed_output.write(data)

I tried using the System.IO.Compression.DeflateStream class, but for every file I try it gives me an exception that the file contains invalid data while decoding.

byte[] binary = new byte[1000000];
using (DeflateStream compressed_file = new DeflateStream(new FileStream(@"myfile", FileMode.Open, FileAccess.Read), CompressionMode.Decompress))
       compressed_file.Read(binary, 0, 1000000); //exception here
using (BinaryWriter outputFile = new BinaryWriter(new FileStream(@"output_file", FileMode.Create, FileAccess.Write)))
       outputFile.Write(binary);

//Reading the file like normal with a BinaryReader and then turning it into a MemoryStream also didn't work

I should probably mention that the files are ZLIB compressed files. They start with the 78 9C header.

Upvotes: 1

Views: 5342

Answers (2)

BBC
BBC

Reputation: 406

In .NET 8, there is a ZLibStream library which allows us to decompress lib file.

Here is a code snippet that shows how to use the library

using System.IO.Compression;
...
static string Decompress(string CompressedFileName)
{
    // function takes a filename and returns the decompressed contents
    using (FileStream compressedFileStream = File.Open(CompressedFileName, FileMode.Open))
    {
        using (var ds = new ZLibStream(compressedFileStream, CompressionMode.Decompress))
        {
            using (var sr = new StreamReader(ds))
            {
                return sr.ReadToEnd();
            }
        }
    }
}

Upvotes: 0

DarkAtom
DarkAtom

Reputation: 3171

So, luckily, I found this post: https://stackoverflow.com/a/33855097/10505778

Basically the file must be stripped of its 2 header bytes (78 9C). While the 9C is important in decompression (it specifies whether a preset dictionary has been used or not), I don't need it, but I am pretty sure it is not that difficult to modify this to accomodate it:

byte[] binary, decompressed;
using (BinaryReader file = new BinaryReader(new FileStream(@"myfile", FileMode.Open, FileAccess.Read, FileShare.Read))
    binary = file.ReadBytes(int.MaxValue); //read the entire file
output = new byte[int.MaxValue];
int outputSize;
using (MemoryStream memory_stream = new MemoryStream(binary, false))
{
    memory_stream.Read(decompressed, 0, 2); //discard 2 bytes
    using (DeflateStream compressed_file = new DeflateStream(memory_stream, CompressionMode.Decompress)
        outputSize = compressed_file.Read(decompressed, 0, int.MaxValue);
}
binary = new byte[outputSize];
Array.Copy(decompressed, 0, binary, 0, outputSize);
using (BinaryWriter outputFile = new BinaryWriter(new FileStream(@"output_file", FileMode.Create, FileAccess.Write)))
    outputFile.Write(binary);

Upvotes: 4

Related Questions