Take the 2-minute tour ×

I have a method that takes either a StringReader instance (reading from the clipboard) or a StreamReader instance (reading from a file) and, at present, casts either one as a TextReader instance.

I need it to 'pre-read' some of the source input, then reset the cursor back to the start. I do not necessarily have the original filename. How to I do this?

There is mention of the Seek method of System.IO.Stream but this is not implemented in TextReader, although it is in StreamReader through the Basestream property. However StringReader does not have a BaseStream property

share|improve this question
add comment

4 Answers

up vote 27 down vote accepted

It depends on the TextReader. If it's a StreamReader, you can use:

sr.BaseStream.Position = 0;

(Assuming the underlying stream is seekable, of course.)

Other implementations of TextReader may not have a concept of "rewinding", in the same way that IEnumerable<T> doesn't. In many ways you can think of TextReader as a glorified IEnumerable<char>. It has methods to read whole chunks of data at a time, read lines etc, but it's fundamentally a "forward reading" type.

EDIT: I don't believe StringReader supports any sort of rewinding - you'd be better off recreating the StringReader from the original string, if you can. If that's not feasible, you could always create your own TextReader class which proxies all the "normal" calls to another StringReader, but recreates that proxy instance when it needs to.

share|improve this answer
Thanks for the heads up on BaseStream, I've updated the question so that perhaps the problem can be fully resolved. –  Brendan May 6 '09 at 20:28
Thanks for that, looks like I might have to rethink what is passed to the method using an overload. –  Brendan May 7 '09 at 13:38
add comment

If it is a StreamReader, and if that stream supports seeking, then:

        reader.BaseStream.Seek(0, SeekOrigin.Begin);

However, this is not possible on arbitrary TextReader's. You could perhaps read all of it as a string, then you can use StringReader repeatedly?

share|improve this answer
add comment

I came across your post, and was rather diappointed that this isn't possible. I hacked up something quick which works: just avoid the stringreader altogether:

Stream stream = new MemoryStream((new System.Text.ASCIIEncoding().GetBytes(mystring)), false);
reader = new StreamReader(stream, new System.Text.ASCIIEncoding());

It's not pretty, and it uses ASCII (which was what I needed anyway). Note that with a different encoding this won't work, as you will seek the n'th byte which doesn't have be equal to the n'th character. If you do need that you could do something like

Stream stream = new MemoryStream((new System.Text.UTF32Encoding().GetBytes(mystring)), false);
reader = new StreamReader(stream, new System.Text.UTF32Encoding());

as UTF32 is the only fixed length unicode format.

You can now do

reader.BaseStream.Position = wherever; // or wherever * 4 for the UTF32 variety,
                                       // in your case, the beginning of the string,
                                       // which is always 0 obviously
share|improve this answer
I was doing a search for "32 unicode seek c# streamreader" and you hit the nail on the head with that second snippet. +1 ... I'll go try it out! –  J Coombs Sep 27 '13 at 5:46
Now I just need a 32-bit version of string and StringBuilder so I don't have to mess with surrogate pairs. (Hmm, even that doesn't quite solve parsing a mix of \n and Windows' \r\n newlines, the latter which are annoyingly similar to a surrogate pair.) –  J Coombs Sep 27 '13 at 5:53
yeah, have fun with that ;) If you need seeking, you're in a bit of pain, so if you can avoid it, work around it. As soon as you have strings again, you are back in sanity-land, and surrogate pairs can be left to the String datatype which handles all the difficulty for you, and seeking a lot in a stream is a smell anyway. As far as \r goes, the best thing you can do with that IMO is to always skip/ignore it in any parsing. –  Martijn Sep 27 '13 at 9:07
if you're looking to get the string out of that, you can just read it from the reader.Read methods –  Martijn Sep 27 '13 at 9:39
Generally, you shouldn't be working with hand rolled 32-bit strings, but just with strings. The String datatype is UTF-16 under the hood, and should just work(tm) with surrogate pairs. Things like substring should treat a surrogate pair as a single character. What is your specific use case? –  Martijn Sep 28 '13 at 8:15
show 4 more comments

Seek and ye shall find.

Seek(0, SeekOrigin.Begin);

TextReader is derived from StreamReader. StreamReader contains a BaseStream property

share|improve this answer
"TextReader is derived from StreamReader" - other way around. –  Marc Gravell May 6 '09 at 19:56
Yeah, good point Marc. This against most peoples common sense but it it's true. –  jpierson Jan 26 '11 at 21:08
add comment

Your Answer


