2010-11-11 57 views
13

我想將數據發佈到接受壓縮數據的服務器。下面的代碼工作得很好,但它是未壓縮的。我沒有使用壓縮或Gzip beofre,所以任何幫助appriciated。如何壓縮HttpWebRequest POST

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整個字節數組嗎?我是否需要添加其他標題或刪除已存在的標題?

謝謝!

斯科特

回答

3

Page_Load事件:

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

和使壓縮的請求:由裏克施特拉爾

HttpWebRequest and GZip Http Responses

+4

鏈接的文章解釋瞭如何解壓縮在一個響應返回的數據,而不是如何構建請求使用壓縮數據。 – Scott 2010-11-11 19:47:30

+0

@Scott更新。 – 2010-11-12 06:28:12

12

要回答你問的問題,以POST壓縮數據,你只需要用gzip stre包裝請求流am

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

這與請求gzip響應完全不同,這是一個非常常見的事情。

+3

這看起來非常接近我在找的東西。但是,我得到一個「無法關閉流,直到寫入所有字節」異常。仍在調查。 Flush()似乎沒有幫助。另外,我仍然需要知道使用什麼標題。 – Scott 2010-11-11 18:24:01

+0

與@filipov [回答](http://stackoverflow.com/a/23055905/492258)這成爲完整的答案 – 2016-12-20 12:38:45

0

試試這個擴展方法。 流將保持打開(請參閱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

3

我也收到了「無法關閉流,直到所有字節寫入」使用類似的代碼錯誤tnyfst的。問題是我有:

request.ContentLength = binData.Length; 

其中binData是我的壓縮前的原始數據。顯然,壓縮內容的長度會有所不同,所以我就刪除了此行,結束了這段代碼:

using (GZipStream zipStream = new GZipStream(request.GetRequestStream(), CompressionMode.Compress)) 
{ 
    zipStream.Write(binData, 0, binData.Length); 
}