tags:

views:

1476

answers:

3

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

A: 

Seek and ye shall find.

Seek(0, SeekOrigin.Begin);

TextReader is derived from StreamReader. StreamReader contains a BaseStream property

billb
"TextReader is derived from StreamReader" - other way around.
Marc Gravell
+6  A: 

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

sr.BaseStream.Position = 0;
sr.DiscardBufferedData();

(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.

Jon Skeet
Thanks for the heads up on BaseStream, I've updated the question so that perhaps the problem can be fully resolved.
Brendan
Thanks for that, looks like I might have to rethink what is passed to the method using an overload.
Brendan
+5  A: 

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

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

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?

Marc Gravell
Thanks for the heads up on BaseStream, I've updated the question so that perhaps the problem can be fully resolved.
Brendan