2010-08-08 128 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 
} 
相關問題