Come risolvere il numero magico di Gzip mancante

Ho una stringa che I Gzip sul server e scaricare in un client utilizzando la class WebClient. Quando provo a decomprimerlo, ricevo il messaggio di errore che manca il numero magico. Ho provato sia la class GZipStream che i metodi ICSharpLib per risolvere questo problema, quindi sono in perdita.

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

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

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. PS Sto usando la stringa Base64 per poter passare avanti e indietro sul web. Questo potrebbe in effetti essere l’area in cui mi sto cacciando da quando non ho mai fatto richieste e risposte web tra un’app desktop e un servizio web.

Innanzitutto, non penso che lo snippet sia valido, perché 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.

MODIFICARE:

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

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

Quindi si eliminerebbe la prima riga della funzione (la decodifica da base64). Nota che stiamo rinominando encryptedFile in file compresso.

La linea:

 memStream.ReadByte(); 

non dovrebbe essere lì Stai leggendo un byte e lo scarti. Se tutto è come ci aspettiamo che il byte sia 0x1F, parte del numero magico gzip.

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

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

Quindi, si utilizza StreamReader direttamente su quello:

 StreamReader sr = new StreamReader(stream); 

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

 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"]; //... }