[英]Error "This stream does not support seek operations" in C#
我正在嘗試使用byte
流從 url 獲取圖像。 但我收到此錯誤消息:
此流不支持查找操作。
這是我的代碼:
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();
}
編輯:
我使用反射器檢查過,它是對 stream.Length 的調用失敗了。 GetResponseStream 返回一個 ConnectStream,並且該類的 Length 屬性會引發您看到的異常。 正如其他海報所提到的,您無法可靠地獲得 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) 不能保證它是正確的。
相反,您應該:
Stream.Read
方法的固定長度byte[]
List<byte>
List.AddRange
將固定長度緩沖區的內容附加到字節列表中請注意,對Read
的最后一次調用將返回少於您要求的完整字節數。 確保您只將該字節數附加到您的List<byte>
而不是整個byte[]
,否則您將在列表末尾得到垃圾。
如果服務器未在 HTTP 標頭中發送長度規范,則流大小未知,因此您在嘗試使用Length
屬性時會收到錯誤消息。
以較小的塊讀取流,直到到達流的末尾。
對於圖像,您根本不需要讀取字節數。 只需這樣做:
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 = resp.GetResponseStream() )
{
img = Image.FromStream(stream);
// then use the image
}
也許您應該使用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
。
無法從流中讀取流的長度,因為接收方不知道發送方將發送多少字節。 嘗試將協議放在 http 之上,並將長度作為流中的第一項發送。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.