【问题标题】:How Decompress Gzipped Http Get Response in c#c#中如何解压Gzipped Http获取响应
【发布时间】:2018-02-02 09:20:38
【问题描述】:

想要解压缩从 API 获取的 GZipped 响应。尝试了下面的代码,它总是返回如下:-

\u001f�\b\0\0\0\0\0\0\0�Y]o........

我的代码是:

 private string GetResponse(string sData, string sUrl)
 {
      try
      {
           string script = null;
           try
           {
                string urlStr = @"" + sUrl + "?param=" + sData;

                Uri url = new Uri(urlStr, UriKind.Absolute);

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                     script = reader.ReadToEnd();
                }      
           }
           catch (System.Net.Sockets.SocketException)
           {
                // The remote site is currently down. Try again next time. 
           }
           catch (UriFormatException)
           {
                // Only valid absolute URLs are accepted 
           }

           return script;
      }
      catch (Exception ex)
      {
           throw new Exception(ex.ToString());
      }
 }

我从许多自动解压的参考资料中找到了上面的代码。但最终,它对我不起作用。为了解压压缩数据,我尝试了下面的函数,

 private string DecompressGZIP(string compressedText)
 {
      byte[] gZipBuffer = Convert.FromBase64String(compressedText);
      using (var memoryStream = new MemoryStream())
      {
           int dataLength = BitConverter.ToInt32(gZipBuffer, 0);
           memoryStream.Write(gZipBuffer, 4, gZipBuffer.Length - 4);

           var buffer = new byte[dataLength];

           memoryStream.Position = 0;
           using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
           {
                gZipStream.Read(buffer, 0, buffer.Length);
           }

           return Encoding.UTF8.GetString(buffer);
      }
 }

但是,由于以下异常,它本身在第一行代码中也失败了:

System.FormatException: '输入不是有效的 Base-64 字符串,因为它包含非 base 64 字符、两个以上的填充字符或填充字符中的非法字符。 '

由于我是初学者,希望你们指导我.....提前谢谢....

【问题讨论】:

标签: c# get request gzip compression


【解决方案1】:

这是负责解码 gzip 流的基本位:

var clientHandler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }; 
var client = new HttpClient(clientHandler); 

【讨论】:

  • 你太棒了!!
【解决方案2】:

只需将我的功能更改如下,这对我来说非常有用:

private JObject PostingToPKFAndDecompress(string sData, string sUrl)
        {
            var jOBj = new JObject();
            try
            {

                try
                {
                    string urlStr = @"" + sUrl + "?param=" + sData;


                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlStr);
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    Stream resStream = response.GetResponseStream();

                    var t = ReadFully(resStream);
                    var y = Decompress(t);

                    using (var ms = new MemoryStream(y))
                    using (var streamReader = new StreamReader(ms))
                    using (var jsonReader = new JsonTextReader(streamReader))
                    {
                        jOBj = (JObject)JToken.ReadFrom(jsonReader);
                    }


                }
                catch (System.Net.Sockets.SocketException)
                {
                    // The remote site is currently down. Try again next time. 
                }

            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
            return jOBj;
        }

        public static byte[] ReadFully(Stream input)
        {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }

        public static byte[] Decompress(byte[] data)
        {
            using (var compressedStream = new MemoryStream(data))
            using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
            using (var resultStream = new MemoryStream())
            {
                zipStream.CopyTo(resultStream);
                return resultStream.ToArray();
            }
        }

【讨论】:

  • 一个复杂问题的复杂答案。问题上的 cmets 指出了一个更好的解决方案。这是一个澄清:var clientHandler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }; var client = new HttpClient(clientHandler); 将负责解码 gzipped 流
  • 是的——理论上你说的应该有效。但它并不总是特别是在处理 Http 301、302 等时。人。令人作呕的重定向。然后 - 由于一些模糊的原因 - 减压被“错过”,你最终必须自己做!
  • 发现响应是用 Brotoli 编码的(??不管是什么 eff ??)黑猩猩脱颖而出!
  • @henon 您应该添加您的评论作为答案,因为它会导致更简洁的代码。
  • @BerendEngelbrecht 我做了,如果你能做得更好,请随时编辑。
猜你喜欢
  • 1970-01-01
  • 2020-11-13
  • 1970-01-01
  • 2018-08-25
  • 2021-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多