代码之家  ›  专栏  ›  技术社区  ›  Scott

如何压缩HttpWebRequest POST

  •  14
  • Scott  · 技术社区  · 14 年前

    我试图将数据发布到接受压缩数据的服务器。下面的代码工作得很好,但它是未压缩的。我没有使用压缩或Gzip beofre,因此任何帮助都会被告知。

    HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
      request.Timeout = 600000;
      request.Method = verb;  // POST    
      request.Accept = "text/xml";
    
      if (!string.IsNullOrEmpty(data))
      {
        request.ContentType = "text/xml";        
    
        byte[] byteData = UTF8Encoding.UTF8.GetBytes(data);
        request.ContentLength = byteData.Length;       
    
        // Here is where I need to compress the above byte array using GZipStream
    
        using (Stream postStream = request.GetRequestStream())
        {
          postStream.Write(byteData, 0, byteData.Length);         
        }
      }      
    
      XmlDocument xmlDoc = new XmlDocument();
      HttpWebResponse response = null;
      StreamReader reader = null;
      try
      {
        response = request.GetResponse() as HttpWebResponse;
        reader = new StreamReader(response.GetResponseStream());
        xmlDoc.LoadXml(reader.ReadToEnd());
      }
    

    是否对整个字节数组执行gzip操作?我需要添加其他邮件头还是删除已经存在的邮件头?

    谢谢!

    -斯科特

    4 回复  |  直到 14 年前
        1
  •  13
  •   tnyfst    14 年前

    为了回答您提出的问题,为了发布压缩数据,您只需要用gzip流包装请求流

     using (Stream postStream = request.GetRequestStream())
     {
        using(var zipStream = new GZipStream(postStream, CompressionMode.Compress))
        {
            zipStream.Write(byteData, 0, byteData.Length);         
        }
     }
    

    这与请求gzip响应完全不同,后者是一种更常见的操作。

        2
  •  4
  •   filipov    10 年前

    我还收到“在写入所有字节之前无法关闭流”错误,错误代码与tnyfst类似。问题是我有:

    request.ContentLength = binData.Length;
    

    其中binData是压缩之前的原始数据。显然,压缩内容的长度会有所不同,所以我删除了这一行,最后得到了以下代码:

    using (GZipStream zipStream = new GZipStream(request.GetRequestStream(), CompressionMode.Compress))
    {
        zipStream.Write(binData, 0, binData.Length);
    }
    
        3
  •  3
  •   Ramiz Uddin    14 年前

    Page_Load 事件:

            Response.AddHeader("Content-Encoding", "gzip");
    

    对于压缩请求:

    HttpWebRequest and GZip Http Responses 通过 瑞克·斯特拉尔

        4
  •  0
  •   Oscar Fraxedas    11 年前

    试试这个扩展方法。 流将保持打开状态(请参阅GZipStream构造函数)。 压缩完成后,流位置设置为0。

    public static void GZip(this Stream stream, byte[] data)
    {
        using (var zipStream = new GZipStream(stream, CompressionMode.Compress, true))
        {
            zipStream.Write(data, 0, data.Length);
        }
        stream.Position = 0;
    }
    

    您可以使用以下测试:

    [Test]
    public void Test_gzip_data_is_restored_to_the_original_value()
    {
        var stream = new MemoryStream();
        var data = new byte[]{1,2,3,4,5,6,7,8,9,10};
    
        stream.GZip(data);
    
        var decompressed = new GZipStream(stream, CompressionMode.Decompress);
    
        var data2 = new byte[10];
        decompressed.Read(data2,0,10);
    
        Assert.That(data, Is.EqualTo(data2));
    }
    

    有关详细信息,请参见: http://msdn.microsoft.com/en-us/library/hh158301(v=vs.110).aspx