Pregunta

Tengo una cadena que escribo Gzip en el servidor y la descargo a un cliente usando la clase WebClient. Cuando intento descomprimirlo, aparece el mensaje de error de que falta el número mágico. He intentado tanto la clase GZipStream como los métodos ICSharpLib para resolver esto, así que estoy perdido.

La compresión / descompresión funciona si omito el paso de descarga a través del WebClient (usando DownloadData que devuelve los datos como byte []), por lo que solo puedo suponer que hay algún problema con los datos que se truncan o corrompen de alguna manera , pero como se trata de datos comprimidos, no estoy seguro de cómo depurar esto.

Aquí está el fragmento de código que parece ser la parte ofensiva:

   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
}

Cualquier ayuda sería apreciada. PD Estoy usando la cadena Base64 para poder pasar de un lado a otro de la web. De hecho, esta puede ser el área en la que me estoy metiendo porque no he hecho solicitudes y respuestas web entre una aplicación de escritorio y un servicio web antes.

¿Fue útil?

Solución

Primero, no creo que el fragmento sea válido, porque DownloadString devuelve (como se esperaba) una Cadena.

Ahora, ¿entiendo bien que funciona correctamente cuando usa DownloadData e incorrectamente cuando usa DownloadString? Eso tiene sentido porque no es válido decodificar datos Gzip como Unicode.

EDITAR:

Bien, ToBase64String y FromBase64String deberían estar bien. Pero si puede evitarlo y pasar el byte [] directamente, sería bueno.

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

Entonces se desharía de la primera línea de la función (la decodificación de base64). Tenga en cuenta que estamos cambiando el nombre del archivo cifrado a archivo comprimido.

La línea:

memStream.ReadByte();

no debería estar allí. Estás leyendo un byte y lo descartas. Si todo está como esperamos, el byte es 0x1F, parte del número mágico gzip.

Entonces, creo que estás usando la clase gzip incorrecta. Desea GZipStream . Está construido como:

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

Luego, usa StreamReader directamente en eso:

StreamReader sr = new StreamReader(stream);

Sería útil si supieras la codificación, pero espero que el valor predeterminado sea correcto. Entonces parece correcto a partir de ahí. Entonces, en general obtenemos lo siguiente.

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

    //...
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top