How to create a StreamReader from an existing StreamReader

  • Thread starter Thread starter Anders Olsson
  • Start date Start date
A

Anders Olsson

I need to create a StreamReader which starts from the position of an
existing StreamReader. This way, the second StreamReader can read lines
"ahead" in an own loop, and then I can go back to the outer loop and the
first StreamReader is still where I left it.

I have been trying to do this using this code:

StreamReader sr2 = sr1 //Where sr1 is the existing StreamReader

This seems to work just fine, so I guess this is a supported way of doing
it. The only problem is that when sr2 reaches EOF, sr1 also goes EOF
(EndOfStream). Why is this?

Should I be doing this another way perhaps?

Thanx! /Anders
 
You will have to create two separate StreamReader objects. Otherwise they
share the same BaseStream, and the same position pointer. Compare
sr2.BaseStream.Position and sr1.BaseStream.Position, they are equal.

kevin aubuchon
 
<"Anders Olsson" <ms-publicnews DOT 20 DOT hennish AT spamgourmet DOT
com> said:
I need to create a StreamReader which starts from the position of an
existing StreamReader. This way, the second StreamReader can read lines
"ahead" in an own loop, and then I can go back to the outer loop and the
first StreamReader is still where I left it.

I have been trying to do this using this code:

StreamReader sr2 = sr1 //Where sr1 is the existing StreamReader

This seems to work just fine, so I guess this is a supported way of doing
it. The only problem is that when sr2 reaches EOF, sr1 also goes EOF
(EndOfStream). Why is this?

StreamReader is a reference type. Your line above just sets the value
of sr2 to the value of sr1 - both references to the same object. If
this doesn't immediately make it clear, see
http://www.pobox.com/~skeet/csharp/parameters.html which has a brief
explanation of reference types. (Must write a full article about that
some time...)
Should I be doing this another way perhaps?

Definitely. You'll probably need to write your own buffering reader
though - either that or seek back to the original place in the base
stream and call DiscardBufferedData (assuming your stream supports
seeking).
 
You will have to create two separate StreamReader objects. Otherwise they
share the same BaseStream, and the same position pointer. Compare
sr2.BaseStream.Position and sr1.BaseStream.Position, they are equal.

Ok, but it seems I can't have two different StreamReaders reading the same
file at the same time. :(
 
Jon Skeet said:
http://www.pobox.com/~skeet/csharp/parameters.html which has a brief
explanation of reference types. (Must write a full article about that
some time...)

Hi. Thanks for the explanation. I understand now, that I need two different
StreamReaders (or is it Streams?). Anyway, I don't think this is possible
since the source data is a file. If I try to create a second Stream and
StreamReader, i get a "file in use" exception. (Also see my reply to Kevin's
post).
Definitely. You'll probably need to write your own buffering reader
though - either that or seek back to the original place in the base
stream and call DiscardBufferedData (assuming your stream supports
seeking).

Wow! Writing my own buffering reader sounds a little too complicated for me.
:)

Is there a way to "save" the position of a StreamReader and seek back to it
at after reading a couple of lines ahead? How?

Or would I have to save the current line as a string, close the stream,
reopen it, and seek forward until I get to the same string where I left off?
Sounds like a bad way to to it, performance wise, although the log files are
"only" 3-4 megs in size.

Any other ideas on how to do this?

/Anders
 
<"Anders Olsson" <ms-publicnews DOT 20 DOT hennish AT spamgourmet DOT
com> said:
Hi. Thanks for the explanation. I understand now, that I need two different
StreamReaders (or is it Streams?). Anyway, I don't think this is possible
since the source data is a file. If I try to create a second Stream and
StreamReader, i get a "file in use" exception. (Also see my reply to Kevin's
post).

You should be able to open the file twice if you open it just for
reading, and with file sharing.
Wow! Writing my own buffering reader sounds a little too complicated for me.
:)

Is there a way to "save" the position of a StreamReader and seek back to it
at after reading a couple of lines ahead? How?

Well, you can use BaseStream.Position, but then you'll be slightly out
due to buffering :(
Or would I have to save the current line as a string, close the stream,
reopen it, and seek forward until I get to the same string where I left off?
Sounds like a bad way to to it, performance wise, although the log files are
"only" 3-4 megs in size.

Any other ideas on how to do this?

I think opening the file twice is the best bet. Use FileAccess.Read and
FileShare.Read when opening the file, and you should be okay.
 
Back
Top