C# – Fast compression in C++ and decompression in C#

ccompression

Overview

I am working on a client-server application. The client is written in C++ (working on Windows, planning to support Linux) and the server is a .NET RESTful service. I need to HTTP POST some data to the server. The data is a unicode string that I need to compress using any fast compression algorithm (needs to be light on CPU). On the server I need to decompress raw bytes and get a string.

Problem

I cannot decompress raw bytes and I end up with decompressor's output buffers stay intact.

I tried

I have tried using Google Snappy, there is only a C/C++ version and any .NET ports don't appear to be finished. I also checked LZ4, where compression/decompression works in a single language, but when I try to use both – I cannot decompress data correctly (the decompressed bytes are set to 0s).

Question

Has anyone tried using a fast C/C++ compression and C# decompression? Any recommendations?

Client application shall not use more than 5% of CPU – that's a vague requirement I have. I plan to try gzip and maybe deflate, but I am not sure if I can configure compression levels there or whether it will work in both C/C++ and C#. Client collects some near real time data into a small buffer, when that buffer gets full it shall be compressed and POSTed. The whole OS process shall take less than 5% of the machine's CPU. A buffer is roughly posted 2 times a second which creates a traffic of about 2Kb/sec.

Best Answer

If anybody interested I ended up using gzip from zlib. Never figured out why LZ4 doesn't work, as suggested in the comments this could be an endianess problem or a 64/32-bit mismatch. However, I tested this on a single machine compressing and decompressing a local file. The same compilation settings worked for gzip.

C/C++ sample compressor code

int compress_one_file(char *infilename, char *outfilename)
 {
    FILE *infile = fopen(infilename, "rb");
    gzFile outfile = gzopen(outfilename, "wb");
    if (!infile || !outfile) return -1;

    char inbuffer[128];
    int num_read = 0;
    unsigned long total_read = 0, total_wrote = 0;
    while ((num_read = fread(inbuffer, 1, sizeof(inbuffer), infile)) > 0) {
       total_read += num_read;
       gzwrite(outfile, inbuffer, num_read);
    }
    fclose(infile);
    gzclose(outfile);
 }

C# sample decompressor code

public static void Decompress(FileInfo fileToDecompress)
{
    using (FileStream originalFileStream = fileToDecompress.OpenRead())
    {
        string currentFileName = fileToDecompress.FullName;
        string newFileName = currentFileName + ".decompressed";

        using (FileStream decompressedFileStream = File.Create(newFileName))
        {
            using (GZipStream decompressionStream = 
                new GZipStream(originalFileStream, CompressionMode.Decompress))
            {
                decompressionStream.CopyTo(decompressedFileStream);
            }
        }
    }
}
Related Topic