문제

서버에서 gzip하고 webclient 클래스를 사용하여 클라이언트에 다운로드하는 문자열이 있습니다. 압축을 풀려고 할 때 마법 번호가 누락되었다는 오류 메시지가 나타납니다. 나는 gzipstream 클래스와 이것을 해결하는 icsharplib 방법을 모두 시도 했으므로 손실 중입니다.

WebClient를 통해 다운로드 단계를 생략하면 압축/감압 (데이터를 바이트 []로 반환하는 다운로드 데이터 사용)를 사용하면 데이터가 잘린 방법에 문제가 있다고 가정 할 수 있지만 그 이후로는 일부 문제가 있다고 가정 할 수 있습니다. 압축 데이터입니다. 이것을 디버깅하는 방법을 잘 모르겠습니다.

다음은 불쾌한 부분으로 보이는 코드 스 니펫입니다.

   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 문자열을 사용하고 있습니다. 실제로 데스크탑 앱과 웹 서비스간에 웹 요청과 응답을하지 않았기 때문에 실제로 내가 엉망인 영역 일 수 있습니다.

도움이 되었습니까?

해결책

첫째, DownloadString이 문자열을 반환하기 때문에 스 니펫이 유효하다고 생각하지 않습니다.

이제 DownloadData를 사용할 때 올바르게 작동하고 DownloadString을 사용할 때 잘못 작동한다는 것을 이해합니까? GZIP 데이터를 유니 코드로 디코딩하는 것이 유효하지 않기 때문에 의미가 있습니다.

편집하다:

좋아, Tobase64String과 Frombase64String은 괜찮을 것입니다. 그러나 당신이 그것을 피하고 바이트를 직접 통과시킬 수 있다면, 그것은 좋을 것입니다.

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

그런 다음 함수의 첫 번째 줄 (Base64의 디코드)을 제거합니다. 우리는 compressedfile로 암호화 된 파일을 바꾸고 있습니다.

라인 :

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

    //...
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top