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

时间:2010-08-08 10:45:53

标签: c# stream byte

我正在尝试使用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;

我做错了什么人?

7 个答案:

答案 0 :(得分:69)

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

编辑:

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

答案 1 :(得分:12)

改为使用StreamReader

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

StreamReader reader = new StreamReader(myResp.GetResponseStream());
return reader.ReadToEnd();

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

答案 2 :(得分:6)

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

相反,你应该:

  1. 创建传递给byte[]方法
  2. 的固定长度Stream.Read
  3. 创建List<byte>
  4. 每次阅读后,调用List.AddRange将固定长度缓冲区的内容追加到字节列表中
  5. 请注意,对Read的最后一次调用将返回少于您要求的完整字节数。确保您只将这个字节数附加到List<byte>而不是整个byte[],否则您的列表末尾会出现垃圾。

答案 3 :(得分:5)

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

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

答案 4 :(得分:0)

由于接收方不知道发送方将发送多少字节,因此无法从流中读取流的长度。尝试将协议放在http之上,并将长度作为流中的第一项发送。

答案 5 :(得分:0)

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

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
}

答案 6 :(得分:0)

也许您应该使用System.Net.WebClient API。如果已经使用client.OpenRead(url),请使用client.DownloadData(url)

var client = new System.Net.WebClient();
byte[] buffer = client.DownloadData(url);
using (var stream = new MemoryStream(buffer))
{
    ... your code using the stream ...
}

很明显,这会在创建Stream之前下载所有内容,因此可能无法达到使用Stream的目的。 webClient.DownloadData("https://your.url")得到一个字节数组,然后可以将其变成MemoryStream