2010-08-08 130 views
35

我试图从一个URL使用byte流获取图像。但我收到此错误消息:错误“此流不支持查找操作”在C#中

此流不支持查找操作。

这是我的代码:

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; 

什么我做错了什么人?

+0

类似的情况得到的回答是,可能帮助,请参阅:http://stackoverflow.com/a/43981770/2791237 – 2017-05-15 14:22:40

回答

63

你可能想要这样的东西。要么检查长度失败,要么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响应的长度,所以这是有道理的。

+0

嗨ngoozeff,谢谢,这就是诀窍!似乎工作! – Yustme 2010-08-08 11:37:18

+5

流长度失败,但response.ContentLength返回有效长度。 – andleer 2010-09-20 20:35:40

+0

不需要像这样将它写入字节,但是,对于图像,如果要将其用作图像。见下面我的答案。 – vapcguy 2014-11-08 04:30:20

0

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

5

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

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

6

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

相反,你应该:

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

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

+0

嗨,我有点糊涂了。我的代码应该如何呢? – Yustme 2010-08-08 10:58:27

+0

@Yustme,'var buffer = new List (); while(true){byte [] tmpBuffer = new byte [1024]; int bytesRead = br.Read(tmpBuffer,0,tmpBuffer.length); buffer.AddRange(tmpBuffer.Take(bytesRead)); if(bytesRead strager 2010-08-08 11:04:00

+0

或使用StreamReader – Justin 2010-08-08 11:07:51

10

使用StreamReader代替:

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

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

(注 - 上面的回报,而不是String的字节数组)

+1

(...然后可以使用Encoding类提供的函数将其转换为字节数组)。 – sunside 2010-08-08 12:55:59

+0

这应该是公认的答案,它比其他方法一! – Couitchy 2014-09-07 17:16:22

+0

如果它有例程或链接如何将它从StreamReader转换为字节或图像。没有这些,我们仍然处于第一位。这根本没有帮助我。 – vapcguy 2014-11-08 04:31:48

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 
} 
相关问题