2012-11-04 246 views
1

我在C#中編寫了一個ASP.NET服務器,需要從外部服務器獲取一堆圖像。我遇到的問題是圖像從我的方法中返回,但它看起來像只有一半加載。WebRequest.GetResponse等待完成

這是瓷磚的外觀,當加載經過我的服務器一樣(這是一個OSM週期地圖瓦片):

tile.png

這是瓷磚的樣子,如果我只是在瀏覽器中打開(來自同一個URL,當然):

5.png

這是很清楚,我認爲所有的字節都沒有過線使得它,但我不知道他們去哪裏迷路。這是我的代碼看起來像:

private byte[] GetTile(string url) 
{ 
    var response = WebRequest.Create(url).GetResponse(); 

    Stream respStr = response.GetResponseStream(); 

    byte[] buf = new byte[response.ContentLength]; 
    respStr.Read(buf, 0, buf.Length); 

    return buf; 
} 

這也不覺得正確的方式來做到這一點。我的字節在哪裏?在我從函數返回之前是否有推薦的方法來等待來自服務器的所有字節?

+1

喬恩斯基特這裏有一個答案的解釋:http://stackoverflow.com/questions/221925 /創建一個字節數組 - 從一個流 – JoshVarty

回答

4

respStr.Read(buf, 0, buf.Length);讀不會機制保障,它會讀取buf.Length字節。你應該檢查它的返回值。或者乾脆,你可以把它複製到使用CopyTo

private byte[] GetTile(string url) 
{ 
    var response = WebRequest.Create(url).GetResponse(); 

    Stream respStr = response.GetResponseStream(); 

    MemoryStream m = new MemoryStream(); 
    respStr.CopyTo(m); 

    return m.ToArray(); 
} 

另一個流也可以使用WebClient這個

private byte[] GetTile(string url) 
{ 
    using (WebClient wc = new WebClient()) 
    { 
     return wc.DownloadData(url); 
    } 
} 
+0

我正在與WebClient解決方案,只是因爲它更乾淨。謝謝! –

1

我只是嘮叨Jon Skeet的答案,因爲它直接適用於你的問題。 Creating a byte array from a stream

也許如果有人搜索類似的關鍵字,這個答案可以指向他們在正確的方向。你不是第一個,絕對不會是最後一個遇到這個問題的人。

Stream.Read()方法並不保證所有字節都將在流中讀取,這在涉及網絡流時尤其明顯。你需要確保你檢查返回值是絕對肯定的是,整個流已被消耗:

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