我正在尝试使用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;
我做错了什么人?
答案 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)不保证是正确的。
相反,你应该:
byte[]
方法Stream.Read
List<byte>
List.AddRange
将固定长度缓冲区的内容追加到字节列表中请注意,对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
。