Domanda

Ho una stringa che Gzip sul server e scarico su un client usando la classe WebClient. Quando provo a decomprimerlo, ricevo il messaggio di errore che manca il numero magico. Ho provato sia la classe GZipStream che i metodi ICSharpLib per risolvere questo problema, quindi sono perplesso.

La compressione / decompressione funziona se ometto il passaggio del download tramite WebClient (utilizzando DownloadData che restituisce i dati come byte []), quindi posso solo supporre che ci sia qualche problema con i dati che vengono troncati o danneggiati in qualche modo , ma poiché si tratta di dati compressi, non sono sicuro di come eseguire il debug di questo.

Ecco lo snippet di codice che sembra essere la parte offensiva:

   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
}

Qualsiasi aiuto sarebbe apprezzato. Post scriptum Sto usando la stringa Base64 per poter passare avanti e indietro sul web. Questa potrebbe in effetti essere l'area in cui mi sto incasinando dal momento che non ho mai fatto richieste e risposte Web tra un'app desktop e un servizio web.

È stato utile?

Soluzione

Innanzitutto, non credo che lo snippet sia valido, poiché DownloadString restituisce (come previsto) una stringa.

Ora, ho capito bene che funziona correttamente quando si utilizza DownloadData e in modo errato quando si utilizza DownloadString? Questo ha senso perché non è valido per decodificare i dati Gzip come Unicode.

EDIT:

Va ??bene, ToBase64String e FromBase64String dovrebbero essere a posto. Ma se puoi evitarlo e passare direttamente il byte [], andrebbe bene.

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

Quindi eliminerai la prima riga della funzione (la decodifica da base64). Nota che stiamo rinominando file crittografato in file compresso.

La linea:

memStream.ReadByte();

non dovrebbe essere lì. Stai leggendo un byte e lo scarti. Se tutto è come previsto, quel byte è 0x1F, parte del numero magico di gzip.

Quindi, penso che tu stia usando la classe gzip sbagliata. Desideri GZipStream . È costruito come:

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

Quindi, usi StreamReader direttamente su questo:

StreamReader sr = new StreamReader(stream);

Sarebbe utile se conoscessi la codifica, ma speriamo che il valore predefinito sia corretto. Quindi sembra corretto da lì. Quindi, nel complesso otteniamo il seguito.

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"];

    //...
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top