2012-11-04 249 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(); 
    } 
}