2013-10-23 28 views
1

我有這樣的代碼,調用this sample API call of the game Guild Wars 2HttpWebRequest的部分未能得到數據

 HttpWebRequest request = HttpWebRequest.Create("https://api.guildwars2.com/v1/events.json?world_id=1001") as HttpWebRequest; 
     HttpWebResponse response = request.GetResponse() as HttpWebResponse; 

     byte[] bytes = new byte[response.ContentLength]; 
     Stream stream = response.GetResponseStream(); 
     stream.Read(bytes, 0, bytes.Length); 
     string result = Encoding.Default.GetString(bytes); 

這是一個示例調用官方激戰2 API和應該返回事件的JSON格式的信息列表和它們的狀態。

如果您在瀏覽器中調用該地址並將數據粘貼到文本編輯器中,它會提供正確的JSON字符串,其大小超過300 kb。

但是,當由此代碼調用並查看生成的字節數組時,第一個3800-3900字節被正確填充(該數字在呼叫之間略有不同),但其餘全部爲零。

response.ContentLength指示流的正確長度,大於300k,並且使用stream.ReadByte()進行測試告訴我流確實傳遞了那些300k,它僅在3850字節標記之後爲0。

在我的代碼中是否有錯誤,或者可能導致此問題?我能否以另一種方式調用API以獲得正確的完整響應?

+0

可能重複【什麼是閱讀的GetResponseStream()的最好方法?(http://stackoverflow.com/questions/137285/what-is-最好的方式來讀取getresponsestream) – CodeCaster

回答

3

對流的Read操作返回實際讀取的字節數。您應該繼續呼叫stream.Read(),直到它返回0.數據根本還沒有到達。

Read不會阻塞的原因是某些應用程序可能已經開始處理部分數據。

你可以使用下面的代碼:的

HttpWebRequest request = HttpWebRequest.Create("https://api.guildwars2.com/v1/events.json?world_id=1001") as HttpWebRequest; 
HttpWebResponse response = request.GetResponse() as HttpWebResponse; 

byte[] bytes; 
using (Stream stream = response.GetResponseStream()) 
using (MemoryStream buffer = new MemoryStream((int)response.ContentLength)) 
{ 
    byte[] chunk = new byte[4096]; 
    int bytesRead; 
    while ((bytesRead = stream.Read(chunk, 0, chunk.Length)) > 0) 
    { 
     buffer.Write(chunk, 0, bytesRead); 
    } 
    bytes = buffer.ToArray(); 
} 
+0

謝謝,這工作。這是什麼背景?這是API方面的限制,如速度限制或塊大小? – Hackworth

+1

「Read()」提前返回的原因是,某些應用程序(例如流式視頻)可以在請求完成之前開始處理數據。在我的例子中,4096的塊大小可能就是任何值。該值應該小於您一次收到的最大數據量,但如果它太小,代碼將浪費處理能力。 –