我正在用C#编写一个ASP.NET服务器,需要从外部服务器获取一堆图像。我遇到的问题是图像是从我的方法返回的,但它看起来只有一半。
这是通过我的服务器加载瓷砖时的样子(它是OSM循环地图图块):
如果我只是在浏览器中打开它(当然是从相同的URL),这就是瓷砖的样子:
我很清楚,所有的字节都没有通过电线,但我不确定它们会在哪里丢失。这就是我的代码:
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;
}
这也不是正确的方法。我的字节在哪里?在我从函数返回之前,是否有推荐的方法等待服务器的所有字节到达?
答案 0 :(得分:4)
respStr.Read(buf, 0, buf.Length);
Read不保证它会读取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);
}
}
答案 1 :(得分:1)
我只是嘲笑Jon Skeet的答案,因为它直接适用于你的问题。 Creating a byte array from a stream
如果有人搜索类似的关键字,这个答案可能会指向正确的方向。你不是第一个,绝对不会是最后一个遇到这个问题的人。
Stream.Read()
方法不保证将在Stream中读取所有字节,这在引用网络流时尤其明显。您需要确保检查返回值以确保整个流已被消耗:
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();
}
}