Error "This stream does not support seek operations" in C#
Solution 1
You probably want something like this. Either checking the length fails, or the BinaryReader is doing seeks behind the scenes.
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();
}
edit:
I checked using reflector, and it is the call to stream.Length that fails. GetResponseStream returns a ConnectStream, and the Length property on that class throws the exception that you saw. As other posters mentioned, you cannot reliably get the length of a HTTP response, so that makes sense.
Solution 2
Use a StreamReader instead:
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
WebResponse myResp = myReq.GetResponse();
StreamReader reader = new StreamReader(myResp.GetResponseStream());
return reader.ReadToEnd();
(Note - the above returns a String
instead of a byte array)
Solution 3
You can't reliably ask an HTTP connection for its length. It's possible to get the server to send you the length in advance, but (a) that header is often missing and (b) it's not guaranteed to be correct.
Instead you should:
- Create a fixed-length
byte[]
that you pass to theStream.Read
method - Create a
List<byte>
- After each read, call
List.AddRange
to append the contents of your fixed-length buffer onto your byte list
Note that the last call to Read
will return fewer than the full number of bytes you asked for. Make sure you only append that number of bytes onto your List<byte>
and not the whole byte[]
, or you'll get garbage at the end of your list.
Solution 4
If the server doesn't send a length specification in the HTTP header, the stream size is unknown, so you get the error when trying to use the Length
property.
Read the stream in smaller chunks, until you reach the end of the stream.
Solution 5
With images, you don't need to read the number of bytes at all. Just do this:
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
}
Yustme
Updated on July 21, 2022Comments
-
Yustme almost 2 years
I'm trying to get an image from an url using a
byte
stream. But i get this error message:This stream does not support seek operations.
This is my code:
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;
What am i doing wrong guys?
-
Yustme almost 14 yearsHi, I'm kind of confused now. how should my code look like then?
-
strager almost 14 years@Yustme,
var buffer = new List<byte>(); while (true) { byte[] tmpBuffer = new byte[1024]; int bytesRead = br.Read(tmpBuffer, 0, tmpBuffer.length); buffer.AddRange(tmpBuffer.Take(bytesRead)); if (bytesRead < tmpBuffer.length) { break; } }
-
Yustme almost 14 yearsHi ngoozeff, thanks, that did the trick! Seems to be working!
-
sunside almost 14 years(... which then can be converted to a byte array using functions provided by the Encoding classes.)
-
andleer almost 14 yearsThe stream length fails but the response.ContentLength does return a valid length.
-
vapcguy over 9 yearsDon't need to get it into bytes like this, though, for an image, if you want to use it as an image. See my answer, below.
-
vapcguy over 9 yearsIf it had the routines or link on how to get it from a StreamReader into bytes, or an image. Without that, we are still at square one, I'd say. This did not help me at all.
-
alexkovelsky over 8 yearsYou don't need to do the
do { ... }
, you can usestream.CopyTo(ms);
instead. -
Negar about 7 yearsI use this code, but my memorystream throw an exception "readtimeout & writetimeout" Also my stream. Canseek = false I tride many solutions but nothing help me
-
user18807217 about 2 yearsGreat, but
StreamReader
does not support binary