0

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.

Community
  • 1
  • 1
DarkAtom
  • 2,589
  • 1
  • 11
  • 27
  • Flagging my question for opinion based answers...really? I never asked for the best way to do it. I asked for a way to do it, that's what SO is for, right? I never asked for any software library or anything – DarkAtom Jul 06 '20 at 11:46
  • 1
    Have you looked at [System.IO.Compression.DeflateStream](https://learn.microsoft.com/en-us/dotnet/api/system.io.compression.deflatestream?view=netcore-3.1?view=netcore-3.1)? – Jon Skeet Jul 06 '20 at 11:46
  • @JonSkeet I did, but for some reason it throws invalid input exceptions on all files I try (files that actually work with the python library, so they are not invalid format or anything) – DarkAtom Jul 06 '20 at 11:50
  • 2
    @DarkAtom You should just post your attempt and the Exception than – nanu_nana Jul 06 '20 at 11:53
  • Is the zip file an archive containing several files? (standard .zip) – Magnus Jul 06 '20 at 11:56
  • @Magnus: I see no indication that it's a zip file at all. – Jon Skeet Jul 06 '20 at 11:57
  • It's a zlib file, I mentioned in the first paragraph, but now I also added a link to the docs of the format. – DarkAtom Jul 06 '20 at 12:00
  • Google "NuGet ZLib" and you will get this: https://www.nuget.org/packages/zlib.net/ – Peri Jul 06 '20 at 12:03
  • http://www.componentace.com/zlib_.NET.htm perhaps? – Magnus Jul 06 '20 at 12:05

1 Answers1

4

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);
DarkAtom
  • 2,589
  • 1
  • 11
  • 27