错误“此stream不支持查找操作”在C#

我试图从一个url使用bytestream获取图像。 但是我得到这个错误消息:

此stream不支持查找操作。

这是我的代码:

 byte[] b; HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url); WebResponse myResp = myReq.GetResponse(); Stream stream = myResp.GetResponseStream(); int i; using (BinaryReader br = new BinaryReader(stream)) { i = (int)(stream.Length); b = br.ReadBytes(i); // (500000); } myResp.Close(); return b; 

我做错了什么人?

你可能想要这样的东西。 要么检查长度失败,要么BinaryReader正在幕后寻找。

 HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url); WebResponse myResp = myReq.GetResponse(); byte[] b = null; using( Stream stream = myResp.GetResponseStream() ) using( MemoryStream ms = new MemoryStream() ) { int count = 0; do { byte[] buf = new byte[1024]; count = stream.Read(buf, 0, 1024); ms.Write(buf, 0, count); } while(stream.CanRead && count > 0); b = ms.ToArray(); } 

编辑:

我使用reflection器进行检查,这是对stream.Length调用失败。 GetResponseStream返回一个ConnectStream,并且该类的Length属性引发您所看到的exception。 正如其他海报提到的,你不能可靠地得到HTTP响应的长度,所以这是有道理的。

改用StreamReader :

 HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url); WebResponse myResp = myReq.GetResponse(); StreamReader reader = new StreamReader(myResp.GetResponseStream()); return reader.ReadToEnd(); 

(注意 – 上面的返回String而不是字节数组)

您无法可靠地询问HTTP连接的长度。 有可能让服务器提前给你发送长度,但是(a)这个头部经常被丢失,(b)不能保证是正确的。

相反,你应该:

  1. 创build一个您传递给Stream.Read方法的固定长度的byte[]
  2. 创build一个List<byte>
  3. 每次读取后,调用List.AddRange将固定长度缓冲区的内容追加到字节列表中

请注意,上次Read调用将返回less于您请求的全部字节数。 确保你只把这个字节数附加到你的List<byte>而不是整个byte[] ,否则你会在列表的最后得到垃圾。

如果服务器不在HTTP头中发送长度规范,则stream的大小是未知的,所以在尝试使用Length属性时会出现错误。

以较小的块读取stream,直到到达stream的末尾。

由于接收者不知道发送者将发送多less个字节,所以不能从stream中读取stream的长度。 试着把一个协议放在http的顶部,发送长度作为stream中的第一项。

使用图像,您根本不需要读取字节数。 只要这样做:

 Image img = null; string path = "http://www.example.com/image.jpg"; WebRequest request = WebRequest.Create(path); req.Credentials = CredentialCache.DefaultCredentials; // in case your URL has Windows auth WebResponse resp = req.GetResponse(); using( Stream stream = response.GetResponseStream() ) { img = Image.FromStream(stream); // then use the image }