Compressione veloce in C ++ e decompressione in C #

4

Panoramica

Sto lavorando su un'applicazione client-server. Il client è scritto in C ++ (funziona su Windows, prevede di supportare Linux) e il server è un servizio .NET RESTful. Ho bisogno di HTTP POST alcuni dati al server. I dati sono un unicode string che devo comprimere usando un algoritmo di compressione veloce (deve essere leggero sulla CPU). Sul server ho bisogno di decomprimere i byte grezzi e ottenere una stringa.

Problema

Non riesco a decomprimere i byte grezzi e alla fine i buffer di uscita del decompressore rimangono intatti.

Ho provato

Ho provato a utilizzare Google Snappy , c'è solo una versione C / C ++ e qualsiasi porta .NET don " t sembra essere finito. Ho anche controllato LZ4 , dove compressione / decompressione funziona in una lingua singola , ma quando prova a usare entrambi - Non riesco a decomprimere i dati correttamente (i byte decompressi sono impostati su 0).

Domanda

Qualcuno ha provato a utilizzare una compressione C / C ++ e una decompressione C # veloci? Qualche raccomandazione?

L'applicazione client non deve utilizzare più del 5% della CPU - questo è un requisito impreciso che ho. Ho intenzione di provare gzip e forse sgonfiare, ma non sono sicuro di poter configurare i livelli di compressione lì o se funzionerà sia in C / C ++ che in C #. Il client raccoglie alcuni dati quasi in tempo reale in un piccolo buffer, quando il buffer si riempie deve essere compresso e sottoposto a POST. L'intero processo del sistema operativo impiegherà meno del 5% della CPU della macchina. Un buffer viene pubblicato approssimativamente 2 volte al secondo, il che crea un traffico di circa 2 KB / sec.

    
posta oleksii 07.01.2013 - 23:26
fonte

4 risposte

7

Se qualcuno fosse interessato, ho finito con l'utilizzo di gzip da zlib . Non ho mai capito perché LZ4 non funzioni, come suggerito nei commenti questo potrebbe essere un problema di endianess o una mancata corrispondenza a 64/32 bit. Tuttavia, ho provato questo su una singola macchina comprimendo e decomprimendo un file locale. Le stesse impostazioni di compilazione hanno funzionato con gzip.

Codice del compressore di esempio C / C ++

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);
 }

Codice decompressore campione C #

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);
            }
        }
    }
}
    
risposta data 08.01.2013 - 13:43
fonte
4

Sia LZ4 che Snappy sono stati portati su .NET di recente.

Puoi trovare la porta LZ4 .NET qui al link .
Puoi trovare la porta Snappy .NET (in realtà P / Invoke wrapper) qui al link .

Puoi anche controllare confronto delle prestazioni (delle porte .NET) qui . < br>

Per rispondere alla tua domanda, ho usato entrambi per testare la compressione C ++ e la decompressione C # e funziona bene.

Dichiarazione di non responsabilità : sì, sia LZ4 che Snappy sono stati portati / spostati da me.

    
risposta data 21.02.2013 - 15:52
fonte
0

Dai un'occhiata al formato LZMA di 7-zip. qui

Ho usato solo le loro utilità di compressione (ma non il loro SDK) ma sono eccellenti. Il formato di compressione è portatile attraverso linguaggio e piattaforma e rivendica il supporto per C # e C ++

    
risposta data 08.01.2013 - 07:14
fonte
-2

Devi sviluppare un programma che verrà eseguito nella console. Il tuo programma si chiamerà "TP2.exe" e ha tre parametri:

  1. il nome di un file di input,
  2. un valore booleano (vero o falso) che indica se si desidera comprimere il file di input o scompattare.
  3. il nome del file di output (il risultato verrà scritto su questo file.)

Ad esempio, se si esegue il programma con il seguente comando nella console: TP2.exe test.txt true test2.txt Il tuo programma leggerà il file test.txt come input e scriverà l'output test2.txt del file compresso. Un altro esempio: se si esegue il programma con il seguente comando nella console:

TP2.exe test2.txt false test.txt

Il programma leggerà il file e scriverà test2.txt in output test.txt file decompresso. Il tuo programma dovrebbe utilizzare il metodo di compressione / decompressione semplicemente discusso nel corso si basa sull'utilizzo di un elenco auto organizzato.

Un esempio di file non compresso e un esempio di file compresso è fornito come esempio di CLIC. Perché il lavoro è semplice da fare, puoi supporre che le frasi siano già state tagliate in parole e che ci sia una singola parola per riga.

Infine, a livello di implementazione, si consiglia di utilizzare un elenco collegato per elencare l'auto-organizzato perché sarebbe più efficiente. Una buona idea sarebbe quella di utilizzare un'implementazione della lista collegata della libreria STL.

    
risposta data 05.02.2013 - 15:24
fonte

Leggi altre domande sui tag