C#中的错误"此流不支持搜索操作"

Yus*_*tme 47 c# byte stream

我正在尝试使用byte流从网址获取图像.但我收到此错误消息:

此流不支持搜索操作.

这是我的代码:

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;
Run Code Online (Sandbox Code Playgroud)

我做错了什么人?

ngo*_*eff 71

你可能想要这样的东西.检查长度失败,或者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();
}
Run Code Online (Sandbox Code Playgroud)

编辑:

我检查了使用反射器,它是对stream.Length的调用失败.GetResponseStream返回一个ConnectStream,该类的Length属性抛出您看到的异常.正如其他海报所提到的,您无法可靠地获得HTTP响应的长度,因此这是有道理的.

  • 流长度失败,但response.ContentLength确实返回有效长度. (5认同)
  • 你不需要做`do {...}`,你可以使用`stream.CopyTo(ms);`代替. (3认同)

Jus*_*tin 12

请改用StreamReader:

HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
WebResponse myResp = myReq.GetResponse();

StreamReader reader = new StreamReader(myResp.GetResponseStream());
return reader.ReadToEnd();
Run Code Online (Sandbox Code Playgroud)

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


Tim*_*son 7

您无法可靠地询问HTTP连接的长度.可以让服务器提前向您发送长度,但(a)标题经常丢失,(b)不保证是正确的.

相反,你应该:

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

请注意,最后一次调用Read将返回少于您要求的完整字节数.确保你只将这个字节数附加到你的List<byte>而不是整个上byte[],否则你会在列表的末尾加上垃圾.


Guf*_*ffa 5

如果服务器未在HTTP标头中发送长度规范,则流大小未知,因此在尝试使用该Length属性时会出现错误.

以较小的块读取流,直到到达流的末尾.