2009-06-22 4 views
1

У меня есть строка, которую я Gzip на сервере и загружаю клиенту с использованием класса WebClient. Когда я пытаюсь распаковать его, я получаю сообщение об ошибке «Магический номер». Я пробовал как класс GZipStream, так и методы ICSharpLib для решения этой проблемы, поэтому я в недоумении.Как решить Gzip Magic Number Missing

Сжатие/декомпрессия работает, если я опускаю шаг загрузки через WebClient (используя DownloadData, который возвращает данные как byte []), поэтому я могу только предположить, что есть некоторые проблемы с усечением или повреждением данных как, но поскольку это сжатые данные, я не уверен, как отлаживать это.

Вот фрагмент кода, который, кажется, мешающий часть:

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 
} 

Любая помощь будет оценена. Постскриптум Я использую строку Base64, чтобы иметь возможность проходить туда и обратно по сети. На самом деле это может быть область, в которой я запутался, поскольку раньше я не делал веб-запросов и ответов между настольным приложением и веб-службой.

ответ

5

Во-первых, я не думаю, что фрагмент действителен, потому что DownloadString возвращает (как и ожидалось) строку.

Теперь, правильно ли я понимаю, что он работает правильно при использовании DownloadData и неправильно при использовании DownloadString? Это имеет смысл, потому что недопустимо декодировать данные Gzip как Unicode.

EDIT:

Хорошо, ToBase64String и FromBase64String должно быть в порядке. Но если вы можете избежать этого и передать байт [] напрямую, это будет хорошо.

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

Тогда вы избавитесь от первой строки функции (декодирования из base64). Обратите внимание, что мы переименовываем encryptedFile в compressFile.

Линия:

memStream.ReadByte(); 

там быть не должно. Вы читаете байт и отбрасываете его. Если все так, как мы ожидаем, это байт 0x1F, часть магического числа gzip.

Тогда, я думаю, вы используете неправильный класс gzip. Вы хотите GZipStream. Он построен как:

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

Затем вы используете StreamReader непосредственно на том, что:

StreamReader sr = new StreamReader(stream); 

Это помогло бы, если бы вы знали кодировку, но, надеюсь, по умолчанию будет правильным. Тогда это кажется правильным оттуда. Итак, в целом мы получаем ниже.

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

    //... 
} 
+0

Вы правы. Извините, что я пытался в последний раз попытаться выяснить, могу ли я понять, чего не хватает. – Jared

+0

Спасибо. Теперь код имеет больше смысла, но вы не ответили на мой вопрос. –

+0

У меня есть строка base64, закодированная? Не будет ли это работать? Как передать данные Gzip'ed в веб-службу и из нее? – Jared

Смежные вопросы