views:

207

answers:

2

Hi

I don't know too much about streams in C#. Right now I have a stream that I put into a stream reader and read it. Later on in some other method I need to read the stream(same stream object) but this time I get this error

System.ArgumentException was unhandled by user code
  Message="Stream was not readable."
  Source="mscorlib"
  StackTrace:
       at System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
       at System.IO.StreamReader..ctor(Stream stream)
       at ExtractTitle(Stream file) in :line 33
       at GrabWebPage(String webPath) in :line 62
       at lambda_method(ExecutionScope , ControllerBase , Object[] )
       at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
       at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7()
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
  InnerException:

So I am thinking maybe by reading the stream it goes to the end. Then when I try to read it again it is at the end of the stream and thats why I am getting this error.

So can anyone shed some light on this?

Thanks

+4  A: 

When you read a stream to the end, specifically with StreamReader's ReadToEnd method, you have to Seek it back to the beginning. This can be done like so:

StreamReader sr = new StreamReader(stream);
sr.ReadToEnd();
sr.Seek(0, SeekOrigin.Begin);
sr.ReadToEnd(); // This now works
nasufara
This looks like a better method than just closing it, and looks like the correct answer. +1
Jeremy Morgan
Does StreamReader have seek? I can't find it.
chobo2
No; stream does. Change `sr.Seek` to `stream.Seek` in the code above.
Craig Stuntz
+3  A: 

Your conclusion is correct; once you've reached the end of your stream, you won't be able to read more data until you've reset your position within the stream:

myStream.Position = 0;

This is equivalent to seeking back to the beginning. Note that your stream must support seeking for this to work; not all streams do. You can check this with the CanSeek property.

Michael Petrotta
Well how can I get a stream that does? Like I am trying to "GetResponseStream()" back from an ftp request and this returns a "Stream" this does not support "Seeking" so what should I do?
chobo2
Can you read the entire stream in one go? If so, read it into a byte array, then create a new MemoryStream (which supports seeking) from that array.
Michael Petrotta
How can I read it into a byte array? Like won't I need to figure out the size of the stream first to know how to big to make the byte array?
chobo2
Read it in small chunks (say, 1024 bytes), and write that chunk to the MemoryStream. Jon Skeet's wrote a good answer about this: http://stackoverflow.com/questions/221925/creating-a-byte-array-from-a-stream
Michael Petrotta