Question

J'ai une chaîne que je Gzip sur le serveur et que je télécharge sur un client à l'aide de la classe WebClient. Lorsque j'essaie de le décompresser, je reçois le message d'erreur indiquant que le nombre magique est manquant. J'ai essayé à la fois la classe GZipStream et les méthodes ICSharpLib de résoudre ce problème. Je suis donc perdue.

La compression / décompression fonctionne si j'omet l'étape de téléchargement via WebClient (en utilisant DownloadData qui renvoie les données sous forme d'octet []), de sorte que je ne peux que supposer qu'il y a un problème avec les données tronquées ou corrompues. , mais comme ce sont des données compressées, je ne suis pas sûr de savoir comment déboguer cela.

Voici l'extrait de code qui semble être la partie incriminée:

   byte[] response
   try {
        response = client.DownloadData(Constants.GetSetting("SyncServer"));
   } catch {
        MessageBox.Show("There was a problem synchronizing the data. Please try verify the supplied credentials or try again later.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
   }

   int rows = SQLiteAPI.ImportStatHistoryXML(CurrentUser.User, myCampus, Convert.ToBase64String(response));

public static int ImportStatHistoryXML(Person tempPerson, Campus tempCampus, string xmlFile) {
            byte[] encryptedFile = Convert.FromBase64String(xmlFile);
            MemoryStream memStream = new MemoryStream(encryptedFile);
            memStream.ReadByte();
            GZipInputStream stream = new GZipInputStream(memStream);
            MemoryStream memory = new MemoryStream();
            byte[] writeData = new byte[4096];
            int size;

            while (true) {
                size = stream.Read(writeData, 0, writeData.Length);
                if (size > 0) {
                    memory.Write(writeData, 0, size);
                } else {
                    break;
                }
            }
            stream.Close();
            memory.Position = 0;
            StreamReader sr = new StreamReader(memory);
            string decompressed = sr.ReadToEnd();
            DataSet tempSet = new DataSet();
            StringReader xmlReader = new StringReader(decompressed);
            tempSet.ReadXml(xmlReader);
            DataTable statTable = tempSet.Tables["Stats"];
...more unrelated processing of the table
}

Toute aide serait appréciée. P.S. J'utilise la chaîne Base64 pour pouvoir passer d'un Web à l'autre. C’est peut-être en fait le domaine dans lequel je me trompe, car je n’avais jamais fait de demandes et de réponses Web entre une application de bureau et un service Web auparavant.

Était-ce utile?

La solution

Tout d'abord, je ne pense pas que l'extrait de code soit valide, car DownloadString renvoie (comme prévu) une chaîne.

Maintenant, ai-je bien compris que cela fonctionne correctement lorsque vous utilisez DownloadData et incorrectement lorsque vous utilisez DownloadString? Cela a du sens car il n’est pas valide de décoder les données Gzip au format Unicode.

EDIT:

D'accord, les chaînes ToBase64String et FromBase64String devraient convenir. Mais si vous pouvez l'éviter et passer directement l'octet [], ce serait bien.

public static int ImportStatHistoryXML(Person tempPerson, Campus tempCampus, byte[] compressedFile) {

Ensuite, vous vous débarrasseriez de la première ligne de la fonction (le décodage de base64). Notez que nous renommons encryptedFile en comprimFile.

La ligne:

memStream.ReadByte();

ne devrait pas être là. Vous lisez un octet et le jetez. Si tout se passe comme prévu, l'octet vaut 0x1F et fait partie du nombre magique gzip.

Ensuite, je pense que vous utilisez la mauvaise classe gzip. Vous souhaitez GZipStream . Il est construit comme:

GZipStream stream = new GZipStream(memStream, CompressionMode.Decompress);

Ensuite, vous utilisez StreamReader directement sur ce point:

StreamReader sr = new StreamReader(stream);

Cela vous aiderait si vous connaissiez l’encodage, mais espérons que la valeur par défaut sera correcte. Ensuite, cela semble correct à partir de là. Donc, globalement, nous obtenons le ci-dessous.

public static int ImportStatHistoryXML(Person tempPerson, Campus tempCampus, byte[] compressedFile) {
    MemoryStream memStream = new MemoryStream(compressedFile);
    GZipStream gzStream = new GZipStream(memStream, CompressionMode.Decompress);
    StreamReader sr = new StreamReader(gzStream);
    string decompressed = sr.ReadToEnd();
    DataSet tempSet = new DataSet();
    StringReader xmlReader = new StringReader(decompressed);
    tempSet.ReadXml(xmlReader);
    DataTable statTable = tempSet.Tables["Stats"];

    //...
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top