StreamReaders and position

N

nevin

Hi,
I have a text file of about 12k long. I'm reading the first part of the
file with a readline() and it works ok.
Then in a different function (same open stream) I want to move to the
bottom of the file and retrieve the very last bit of text minus the
trailing spaces.
I'm doing something like:
// move to 200 chars from the end of the stream;
sr.BaseStream.Seek(-200, SeekOrigin.End);
// get the remains of the file
string numrecs = sr.ReadToEnd();
// do some work on the string (remove spaces and some other stuff)
This should move the position of the stream in the file and in the
debugger I can see the position is updated correctly. But when I read
from what should be 200 chars from the end, it reads about 630 chars
from where the ReadLine()'s left off.
So, not only is it not reading from where I want it, ReadToEnd() is not
even doing what it should as from the point it's reading there are qute
a few thousand chars to the end of the file and it's only reading about
630.
Any clues appreciated
Nev
 
N

Nicholas Paldino [.NET/C# MVP]

Nev,

When you change the location of the underlying stream, the StreamReader
is unaware of this. It is possible that it has buffered data, and you are
seeing that buffered data. If you change the underlying position of the
stream without using the StreamReader, you should call the
DiscardBufferedData method on the StreamReader, which will force it to start
from the current position in the stream. This will have a performance
impact, however, it needs to be done any time you change the position of the
underlying stream outside of the StreamReader attached to the stream.

Hope this helps.
 
J

Jon Skeet [C# MVP]

nevin said:
I have a text file of about 12k long. I'm reading the first part of the
file with a readline() and it works ok.
Then in a different function (same open stream) I want to move to the
bottom of the file and retrieve the very last bit of text minus the
trailing spaces.
I'm doing something like:
// move to 200 chars from the end of the stream;
sr.BaseStream.Seek(-200, SeekOrigin.End);
// get the remains of the file
string numrecs = sr.ReadToEnd();
// do some work on the string (remove spaces and some other stuff)
This should move the position of the stream in the file and in the
debugger I can see the position is updated correctly. But when I read
from what should be 200 chars from the end, it reads about 630 chars
from where the ReadLine()'s left off.
So, not only is it not reading from where I want it, ReadToEnd() is not
even doing what it should as from the point it's reading there are qute
a few thousand chars to the end of the file and it's only reading about
630.

The problem is that the StreamReader has a buffer, and it won't try to
read from the stream until the buffer is exhausted.

As the documentation states:

<quote>
StreamReader might buffer input such that the position of the
underlying stream will not match the StreamReader position.
</quote>

You can call DiscardBufferedData immedately after or before the seek to
remedy the problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top