IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Framework .NET Discussion :

[2.0] Comment compresser et décompresser un string


Sujet :

Framework .NET

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 12
    Points : 11
    Points
    11
    Par défaut [2.0] Comment compresser et décompresser un string
    Bonjour à tous,

    Savez vous pourquoi le (minuscule) bout de code suivant ne fonctionne pas?

    Explications:

    J'ai une string toute bête ("abcdef....."), je la copie dans originalBody pour pouvoir comparer après traitement

    Je la compresse et la décompresse (la plupart du code sert à convertir le string en byte[], en streams etc...)

    La ligne qui est supposée décompressée le string retourne 0 et n'écrit rien dans le MemoryStream concernée, comme si il n'y avait rien à décompresser.

    Pourtant si j'appelle la même méthode gzipStream.Read (buffer, 0, buffer.Length) une fois avant la boucle de décompression normale (ie: je décommente la ligne dans le code ci-dessous), elle retourne toujours 0 au premier appel mais lors de l'appelle à la ligne du while(), elle décompresse une partie de la chaine de départ dans le MemoryStream (le buffer étant nettement plus grand que le nombre de byte décompressé)..... En changeant la chaine de départ, il manque plus ou moins de caractères.... C'est très bizarre...

    Difficile de faire un code plus simple pour trouver d'où peut venir l'erreur... Tous les exemples que je trouve fonctionnent bien mais compressent / décompressent des fichiers... Là j'ai besoin de travailler sur des string...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    using System;
    using System.IO;
    using System.IO.Compression;
    using System.Text;
     
    namespace CompressAndDecompress {
        class Program {
            static string body;
            static string originalBody;
            static byte[] bodyGZip;
     
            static void Main (string[] args) {
                body = "abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz";
                originalBody = body;
     
                Compress ();
                Decompress ();
     
                if (originalBody != body)
                    Console.WriteLine ("Marche po...");
                else
                    Console.WriteLine ("Marche");
                Console.ReadKey ();
            }
     
            static void Compress () {
                byte[] bodyBytesArray = Encoding.Unicode.GetBytes (body);
                MemoryStream bodyGzipMemoryStream = new MemoryStream ();
                GZipStream gzipStream = new GZipStream (bodyGzipMemoryStream, CompressionMode.Compress);
                gzipStream.Write (bodyBytesArray, 0, bodyBytesArray.Length);
                bodyGzipMemoryStream.Position = 0;
                bodyGZip = new byte[bodyGzipMemoryStream.Length];
                bodyGzipMemoryStream.Read (bodyGZip, 0, bodyGZip.Length);
            }
     
            static void Decompress () {
                MemoryStream bodyGzipMemoryStream = new MemoryStream (bodyGZip);
                GZipStream gzipStream = new GZipStream (bodyGzipMemoryStream, CompressionMode.Decompress, true);
                MemoryStream bodyMemoryStream = new MemoryStream ();
                byte[] buffer = new byte[1024];
                int readBytes;
                // gzipStream.Read (buffer, 0, buffer.Length);
                while ((readBytes = gzipStream.Read (buffer, 0, buffer.Length)) != 0)
                    bodyMemoryStream.Write (buffer, 0, readBytes);
     
                bodyMemoryStream.Position = 0;
                byte[] bodyBytesArray = new byte[bodyMemoryStream.Length];
                bodyMemoryStream.Read (bodyBytesArray, 0, bodyBytesArray.Length);
                body = Encoding.Unicode.GetString (bodyBytesArray);
            }
        }
    }
    Si vous avez des pistes de reflexion, des idées ou LA solution, je vous en serait hyper reconnaissant parce que je ne sais plus ou chercher...

    Merci d'avance

  2. #2
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    Salut tooff,

    En fait ton probleme est que tu recupere le buffer compressé avant de fermer ton GZipStream et c'est un probleme pour la decompression. Parce que la classe GZipStream ajouter un header qui lui permettera de decompresser un stream compressé en entrée. Et ce header là ne s'ecrit que lorsque tu fermes GZipStream. Dans ton cas précis si tu n'utilise pas de fichier il est plus approprié d'utiliser la classe DeflateStream, qui elle, n'ajoute aucun header et tu auras donc une compression meilleur.

    Donc voila ce qu'il faut faire, si tu n'as pas d'autre problemes alors ca devrait marcher :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    static void Compress () {
                byte[] bodyBytesArray = Encoding.Unicode.GetBytes (body);
                MemoryStream bodyGzipMemoryStream = new MemoryStream ();
                GZipStream gzipStream = new GZipStream (bodyGzipMemoryStream, CompressionMode.Compress);
                gzipStream.Write (bodyBytesArray, 0, bodyBytesArray.Length);
                gzipStream.Close(); 
                bodyGzipMemoryStream.Position = 0;
                bodyGZip = new byte[bodyGzipMemoryStream.Length];
                bodyGzipMemoryStream.Read (bodyGZip, 0, bodyGZip.Length);
            }
    Mehdi Feki : Modérateur .Net

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 12
    Points : 11
    Points
    11
    Par défaut
    Ca fonctionne !!
    Un grand merci !!

  4. #4
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2008
    Messages : 6
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par Mehdi Feki Voir le message
    Salut tooff,

    En fait ton probleme est que tu recupere le buffer compressé avant de fermer ton GZipStream et c'est un probleme pour la decompression. Parce que la classe GZipStream ajouter un header qui lui permettera de decompresser un stream compressé en entrée. Et ce header là ne s'ecrit que lorsque tu fermes GZipStream. Dans ton cas précis si tu n'utilise pas de fichier il est plus approprié d'utiliser la classe DeflateStream, qui elle, n'ajoute aucun header et tu auras donc une compression meilleur.

    Donc voila ce qu'il faut faire, si tu n'as pas d'autre problemes alors ca devrait marcher :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    static void Compress () {
                byte[] bodyBytesArray = Encoding.Unicode.GetBytes (body);
                MemoryStream bodyGzipMemoryStream = new MemoryStream ();
                GZipStream gzipStream = new GZipStream (bodyGzipMemoryStream, CompressionMode.Compress);
                gzipStream.Write (bodyBytesArray, 0, bodyBytesArray.Length);
                gzipStream.Close(); 
                bodyGzipMemoryStream.Position = 0;
                bodyGZip = new byte[bodyGzipMemoryStream.Length];
                bodyGzipMemoryStream.Read (bodyGZip, 0, bodyGZip.Length);
            }
    ou bien gzipStream.Flush(); pour terminer l'écriture des derniers bits < à 1024

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment convertir un TChartTitle en string ?
    Par marsupilami34 dans le forum Langage
    Réponses: 4
    Dernier message: 25/07/2005, 14h14
  2. Réponses: 14
    Dernier message: 29/06/2005, 10h22
  3. Comment compresser un stream ?
    Par lafaryan dans le forum Composants VCL
    Réponses: 2
    Dernier message: 09/01/2005, 20h05
  4. Comment tester qu'un objet String est bien initialisé
    Par Jones dans le forum Servlets/JSP
    Réponses: 8
    Dernier message: 17/09/2004, 11h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo