Pergunta

Eu tenho uma seqüência que eu Gzip no servidor e download para um cliente usando a classe WebClient. Quando tento descompactá-lo, eu recebo a mensagem de erro que o número mágico está faltando. Eu tentei tanto a classe GZipStream e os métodos ICSharpLib de resolver isso, então eu estou em uma perda.

A compressão / descompressão funciona se eu omitir a etapa de download através da WebClient (usando DownloadDataHeader que retorna os dados como byte []), então eu só posso supor que há algum problema com os dados ficando truncado ou corrompido de alguma forma , mas uma vez que é comprimida de dados, eu não tenho certeza como depurar isso.

Aqui está o trecho de código que parece ser a parte ofensora:

   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
}

Qualquer ajuda seria apreciada. P. S. Eu estou usando a seqüência de Base64 para ser capaz de passar frente e para trás em toda a web. Isso pode de fato ser a área que eu estou atrapalhando desde que eu tenho solicitações da web não feito e respostas entre um aplicativo de desktop e um serviço web antes.

Foi útil?

Solução

Em primeiro lugar, eu não acho que o trecho é válido, porque DownloadString retornos (como esperado) uma String.

Agora, eu entendo certo que ele funciona corretamente quando você usa DownloadDataHeader e incorretamente ao usar DownloadString? Isso faz sentido porque não é válida para decodificar dados Gzip como Unicode.

EDIT:

Ok, o ToBase64String e FromBase64String deve estar bem. Mas se você pode evitá-lo e passar o byte [] diretamente, isso seria bom.

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

Em seguida, você iria se livrar da primeira linha da função (a decodificação de Base64). Nota estamos renomeando encryptedFile para compressedFile.

A linha:

memStream.ReadByte();

não deveria estar lá. Você está lendo um byte e descartá-lo. Se tudo é como esperamos que byte é 0x1F, parte do número gzip magia.

Então, eu acho que você está usando a classe gzip errado. Você quer GZipStream . Ele é construído como:

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

Em seguida, use StreamReader diretamente sobre isso:

StreamReader sr = new StreamReader(stream);

Seria bom se você soubesse a codificação, mas espero que o padrão será correta. Então parece correta de lá. Assim, em geral temos a seguir.

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top