2017-11-27 9 views
0

正しくありません。解凍エラー:gzipヘッダ中のマジックナンバーは、私はいくつかの情報を圧縮して解凍しようとしています<a href="https://msdn.microsoft.com/en-us/library/system.io.compression(v=vs.110).aspx" rel="nofollow noreferrer">System.IO.Compression</a></p> <p>に新しいです

圧縮の場合はcode projectを使用しているようです。私は現時点で文字列を圧縮しています。私はこれは私が現時点ではここ

 var zipString = _compressor.Compress(request); 
     using (var sw = new StreamWriter(req.GetRequestStream())) 
     { 
      sw.Write(zipString); 
      sw.Close(); 
     } 

     WebResponse respStream = req.GetResponse(); 
     Stream resp = respStream.GetResponseStream();      
     resp = _compressor.UnCompress(resp); 

public string Compress(string s) 
    { 
     //Transforming string into byte 
     var byteArray = new byte[s.Length]; 
     var indexBa = 0; 
     foreach (var item in s.ToCharArray()) 
     { 
      byteArray[indexBa++] = (byte) item; 
     } 

     //prepare for compress 
     var ms = new MemoryStream(); 
     var sw = new GZipStream(ms, CompressionMode.Compress); 

     //compress 
     sw.Write(byteArray,0,byteArray.Length); 

     //close sw, DO NOT FLUSH because byes will go missing... 
     sw.Close(); 

     //transform byte[] zip data to string 
     byteArray = ms.ToArray(); 
     var sb = new StringBuilder(byteArray.Length); 
     foreach (var item in byteArray) 
     { 
      sb.Append((char) item); 
     } 
     ms.Close(); 
     sw.Dispose(); 
     ms.Dispose(); 
     return sb.ToString(); 
    } 

そして、ここでの圧縮するためのコードでてきたものであるStream

をdocompressしたい解凍するための

解凍のコード

public Stream UnCompress(Stream s) 
    { 
     int readCount; 
     MemoryStream mem = new MemoryStream(); 
     byte[] tmp = new byte[128]; 
     while ((readCount = s.Read(tmp, 0, 128)) != 0) 
     { 
      mem.Write(tmp, 0, readCount); 
     } 
     StreamReader reader = new StreamReader(mem); 
     char[] buffer = new char[mem.Length]; 
     mem.Position = 0; 
     reader.ReadBlock(buffer, 0, (int)mem.Length); 

     byte[] zip = Encoding.UTF8.GetBytes(buffer, 0, (int)mem.Length); 
     Stream wr = new MemoryStream(); 
     wr.Write(zip, 0, zip.Length); 
     wr.Position = 0; 
     using (var stream = new GZipStream(wr, CompressionMode.Decompress)) 
     {     
      mem = new MemoryStream(); 
      while ((readCount = stream.Read(tmp, 0, 128)) != 0) 
      { 
       mem.Write(tmp, 0, readCount); 
      } 
      mem.Position = 0; 
      return mem; 
     }   
    } 

次の行に解凍しながら、この時点で、私はエラーを取得する:

while ((readCount = stream.Read(tmp, 0, 128)) != 0) 
{ 
    mem.Write(tmp, 0, readCount); 
} 

それはちょうどループしながら入力し、言うはありません:gzipヘッダ内

マジックナンバーが正しくありません。

のgzipストリームにあなたが渡していることを確認してください私の解凍方法はstackoverflowのpost

を以下に基づいて2を試してみてください:

 public Stream UnCompress(Stream s) 
     { 
      byte[] byteArray = null; 
      using (var m = new MemoryStream()) 
      { 
       int count; 
       do 
       { 
        byte[] buf = new byte[1024]; 
        count = s.Read(buf, 0, 1024); 
        m.Write(buf, 0, count); 
       } while (s.CanRead && count > 0); 
       byteArray = m.ToArray(); 
      } 
      var indexBa = 0; 
      foreach (var item in s.ToString().ToCharArray()) 
      { 
       byteArray[indexBa++] = (byte) item; 
      } 
      //Prepare for decompress 
      var ms = new MemoryStream(byteArray); 
      var sr = new GZipStream(ms, 
       CompressionMode.Decompress); 

      //Reset variable to collect uncompressed result 
      byteArray = new byte[byteArray.Length]; 

      //Decompress 
      var rByte = sr.Read(byteArray, 0, byteArray.Length); 

      //Transform byte[] unzip data to string 
      var sB = new MemoryStream(rByte); 

      for (var i = 0; i < rByte; i++) 
      { 
       sB.Write(byteArray,0,rByte); 
      } 
      sr.Close(); 
      ms.Close(); 
      sr.Dispose(); 
      ms.Dispose(); 
      return sB; 
     } 

結果:行の同じエラーvar rByte = sr.Read(byteArray, 0, byteArray.Length); アップデート1:

コードプロジェクトの圧縮解除文字列は完全に動作します。

public static string UnZip(string value) 
{ 
    //Transform string into byte[] 
    byte[] byteArray = new byte[value.Length]; 
    int indexBA = 0; 
    foreach (char item in value.ToCharArray()) 
    { 
     byteArray[indexBA++] = (byte)item; 
    } 

    //Prepare for decompress 
    System.IO.MemoryStream ms = new System.IO.MemoryStream(byteArray); 
    System.IO.Compression.GZipStream sr = new System.IO.Compression.GZipStream(ms, 
     System.IO.Compression.CompressionMode.Decompress); 

    //Reset variable to collect uncompressed result 
    byteArray = new byte[byteArray.Length]; 

    //Decompress 
    int rByte = sr.Read(byteArray, 0, byteArray.Length); 

    //Transform byte[] unzip data to string 
    System.Text.StringBuilder sB = new System.Text.StringBuilder(rByte); 
    //Read the number of bytes GZipStream red and do not a for each bytes in 
    //resultByteArray; 
    for (int i = 0; i < rByte; i++) 
    { 
     sB.Append((char)byteArray[i]); 
    } 
    sr.Close(); 
    ms.Close(); 
    sr.Dispose(); 
    ms.Dispose(); 
    return sB.ToString(); 
} 
+1

別に何か他のものから、これは本当に悪い考えであるように、テキストに任意のバイナリデータから変換します。多くの場合正確には正しく伝えられないかもしれない様々な印刷不可能な文字を含むテキストに終わるでしょう。バイト配列を受け入れて返すようにあなたの 'Compress'メソッドを変更することを強くお勧めします。次に、関係する複数の変換のどれが問題を引き起こしているのかを調べることができます。 –

+0

まず、あなたが私の投稿にコメントしたことを祝福します。私はいくつかのことを試してみましたが、いくつかのインデックスでは16進数に関連したエラーが発生しました。それは、圧縮中にいくつかの文字が生成されており、圧縮解除できないことを意味しますか? – Cybercop

+2

圧縮をテキストで操作しているとは思わないでください。 *バイナリ*データ - バイナリ入力、バイナリ出力で動作すると考えてください。別に、入力文字列をバイナリ(おそらく 'Encoding.UTF8.GetBytes')に変換する方法と、絶対に必要な場合に出力をテキストに変換する方法について考えてください(Convert.ToBase64Stringなど) –

答えて

2

コードには多くの問題があるため、最初から別のバージョンを作成する方が簡単です。これを行うことに注意してください:

var byteArray = new byte[s.Length]; 
var indexBa = 0; 
foreach (var item in s.ToCharArray()) 
{ 
    byteArray[indexBa++] = (byte) item; 
} 

文字列をバイト配列に変換することはお勧めできません。代わりに、いくつかのエンコーディングを選択し、それを使って変換しますまた、圧縮結果を文字列として返すことも良い考えではありません。代わりにバイト配列を返します。なぜなら、バイト配列は実際には文字列を表していないからです。これは単なるバイナリデータです。

サンプルコード:

static byte[] Compress(byte[] data) { 
    // `compressed` will contain result of compression 
    using (var compressed = new MemoryStream()) { 
     // source is our original uncompressed data 
     using (var source = new MemoryStream(data)) { 
      using (var gzip = new GZipStream(compressed, CompressionMode.Compress)) { 
       // just write whole source into gzip stream with CopyTo 
       source.CopyTo(gzip); 
      } 
     } 
     return compressed.ToArray(); 
    } 
} 

static byte[] CompressString(string s, Encoding encoding) { 
    return Compress(encoding.GetBytes(s)); 
} 

static string CompressStringToBase64(string s, Encoding encoding) { 
    return Convert.ToBase64String(CompressString(s, encoding)); 
} 

static byte[] Decompress(Stream source) { 
    using (var gzip = new GZipStream(source, CompressionMode.Decompress)) { 
     using (var decompressed = new MemoryStream()) { 
      gzip.CopyTo(decompressed); 
      return decompressed.ToArray(); 
     } 
    } 
} 

static byte[] Decompress(byte[] data) { 
    using (var ms = new MemoryStream(data)) { 
     return Decompress(ms); 
    } 
} 

static string DecompressString(Stream source, Encoding encoding) { 
    return encoding.GetString(Decompress(source)); 
} 

テスト

var source = "Some string"; 
var compressed = CompressString(source, Encoding.UTF8);    
var decompressed = DecompressString(new MemoryStream(compressed), Encoding.UTF8); 
Debug.Assert(source == decompressed); 
関連する問題

 関連する問題