web-dev-qa-db-fra.com

Classe GZipStream ou DeflateStream?

La documentation MSDN me dit ce qui suit:

La classe GZipStream utilise le format de données gzip, qui inclut une valeur de contrôle de redondance cyclique pour détecter la corruption des données. Le format de données gzip utilise le même algorithme de compression que la classe DeflateStream.

Il semble que GZipStream ajoute des données supplémentaires à la sortie (par rapport à DeflateStream). Je me demande, dans quel type de scénario serait-il essentiel d'utiliser GZipStream et non DeflateStream?

53
Captain Sensible

Dégonfler n'est que l'algorithme de compression. GZip est en fait un format.

Si vous utilisez GZipStream pour compresser un fichier (et l'enregistrer avec l'extension .gz), le résultat peut en fait être ouvert par des archiveurs tels que WinZip ou l'outil gzip. Si vous compressez avec un DeflateStream, ces outils ne reconnaîtront pas le fichier.

Si le fichier compressé est conçu pour être ouvert par ces outils, il est essentiel d'utiliser GZipStream au lieu de DeflateStream.

Je considérerais également qu'il est essentiel si vous transférez une grande quantité de données sur un support peu fiable (c'est-à-dire une connexion Internet) et que vous n'utilisez pas un protocole de correction d'erreurs tel que TCP/IP. Par exemple, vous pouvez transmettre sur un port série, un socket brut ou UDP. Dans ce cas, vous voudrez certainement les informations CRC qui sont intégrées au format GZip afin de vous assurer que les données sont correctes.

70
Aaronaught

GZipStream est le même que DeflateStream mais il ajoute du CRC pour garantir que les données ne contiennent aucune erreur.

12
agnain

Eh bien, j'avais complètement tort dans ma première réponse. J'ai recherché dans le code source Mono et constaté que la classe GZipStream redirige réellement ses appels en lecture/écriture (et presque tous les autres) vers des appels appropriés de méthodes d'un objet DeflateStream interne:

public override int Read (byte[] dest, int dest_offset, int count)
{
    return deflateStream.Read(dest, dest_offset, count);
}

public override void Write (byte[] src, int src_offset, int count)
{
    deflateStream.Write (src, src_offset, count);
}

La seule différence est qu'il crée toujours un objet DeflateStream avec un indicateur gzip défini sur true. Ce n'est certainement pas une réponse à votre question, mais peut-être que cela vous aidera un peu.

6
n535

Dito selon Aaronaught

Notez une autre différence importante selon
http://www.webpronews.com/gzip-vs-deflate-compression-and-performance-2006-12 :

J'ai mesuré le DeflateStream à 41% plus rapidement que GZip.

Je n'ai pas mesuré la vitesse, mais j'ai mesuré la taille du fichier pour être appx. le même.

2
Stefan Steiger

Alors que GZipStream semble utiliser DeflateStream pour effectuer la décompression, les deux algorithmes ne semblent pas être interchangeables. Le code de test suivant vous donnera une exception:

        MemoryStream wtt=new MemoryStream();
        using (var gs=new GZipStream(wtt,CompressionMode.Compress,true))
        {
            using (var sw=new StreamWriter(gs,Encoding.ASCII,1024,true))
            {
                sw.WriteLine("Hello");
            }
        }
        wtt.Position = 0;
        using (var ds = new DeflateStream(wtt, CompressionMode.Decompress, true))
        {
            using (var sr=new StreamReader(ds,Encoding.ASCII,true,1024,true))
            {
                var txt = sr.ReadLine();
            }
        }
1
Arsen Zahray