2016-03-01 291 views
0

我想解壓一個GZipped字符串,它是web服務響應的一部分。我有字符串是:解壓縮GZIP流

"[31,-117,8,0,0,0,0,0,0,0,109,-114,65,11,-62,48,12,-123,-1,75,-50,-61,-42,-127,30,122,21,111,-126,94,60,-119,-108,-72,102,44,-48,-75,-93,-21,100,56,-6,-33,-19,20,20,101,57,37,95,-14,94,-34,4,-63,-5,-72,-73,-44,-110,-117,-96,38,-88,26,-74,38,-112,3,117,-7,25,-82,5,24,-116,56,-97,-44,108,-23,28,24,-44,-85,83,34,-41,97,-88,24,-99,23,36,124,-120,94,99,-120,15,-42,-91,-108,91,45,-11,70,119,60,-110,21,-20,12,-115,-94,111,-80,-93,89,-41,-65,-127,-82,76,41,51,-19,52,90,-5,69,-85,76,-96,-128,64,22,35,-33,-23,-124,-79,-55,-1,-2,-10,-87,0,55,-76,55,10,-57,122,-9,73,42,-45,98,-44,5,-77,101,-3,58,-91,39,38,51,-15,121,21,1,0,0]"

我嘗試使用下面的方法來解串:

public static string UnZip(string value) 
     { 
      // Removing brackets from string 
      value = value.TrimStart('['); 
      value = value.TrimEnd(']'); 

      //Transform string into byte[] 
      string[] strArray = value.Split(','); 
      byte[] byteArray = new byte[strArray.Length]; 
      for (int i = 0; i < strArray.Length; i++) 
      { 
       if (strArray[i][0] != '-') 
        byteArray[i] = Convert.ToByte(strArray[i]); 
       else 
       { 
        int val = Convert.ToInt16(strArray[i]); 
        byteArray[i] = (byte)(val + 256); 
       } 
      } 

      //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(); 
     } 

的方法是一個在下面的鏈接的修改版本: http://www.codeproject.com/Articles/27203/GZipStream-Compress-Decompress-a-string

不幸的是,該方法的結果是一個損壞的字符串。更具體地講,我知道,輸入字符串包含壓縮的JSON對象,並輸出字符串只有一些預期字符串:

"{\"rootElement\":{\"children\":[{\"children\":[],\"data\":{\"fileUri\":\"file:////Luciano/e/orto_artzi_2006_0_5_pixel/index/shapefiles/index_cd20/shp_all/index_cd2.shp\",\"relativePath\":\"/i" 

任何想法可能是什麼問題,該如何解決呢?

+1

未壓縮的結果可能會比壓縮數據大。 'new byte [byteArray.Length]'只有在壓縮比爲1:1的情況下才有效。 – Luaan

回答

2

嘗試

public static string UnZip(string value) 
{ 
    // Removing brackets from string 
    value = value.TrimStart('['); 
    value = value.TrimEnd(']'); 

    //Transform string into byte[] 
    string[] strArray = value.Split(','); 
    byte[] byteArray = new byte[strArray.Length]; 
    for (int i = 0; i < strArray.Length; i++) 
    { 
     byteArray[i] = unchecked((byte)Convert.ToSByte(strArray[i])); 
    } 

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

     string str = Encoding.UTF8.GetString(output.GetBuffer(), 0, (int)output.Length); 
     return str; 
    } 
} 

MemoryBuffer()不「重複」的byteArray但它直接支持,所以你不能重用byteArray

我會補充一點,我覺得很有趣,他們將一個277個字符的json「壓縮」爲一個620個字符的字符串化字節數組。

作爲一個旁註,這種方法的內存佔用是超出了屋頂... 620字符串(實際上是一個277字節數組)要解壓導致創建字符串/數組總大小爲4887個字節(包括620個初始字符串)(免責聲明:在執行該方法期間,GC可以回收這部分內存)。對於277字節的字節數組來說這是可以的......但對於更大的內存佔用將變得相當大。