ReadLine and Random Access

D

Danny Smith

Hi,

I need to read a file and be able to:

1. Find the current position in the stream
2. Have access to a handy ReadLine() method.

Obviously the FileStream class supports random access, so you have a Seek()
method and a Position property to find the current stream position, and the
StreamReader class has a ReadLine() method. I thought using these together
would give me what I needed:

StreamReader sr = new StreamReader( File.OpenRead( filename ) );
string line = sr.ReadLine();
long position = sr.BaseStream.Position;

However, this does not work as the StreamReader has buffering which means
the moment a Read call is made, much more than the single line is read from
the BaseStream. Consequently the Position property does not return the
position *immediately* after the end of the line, which is what I need.

This is possible in Java with the RandomAccessFile class, which supports
methods for reading lines and seeking / obtaining the position. Is there
are way to do this in C#?

One option would be to write my own ReadLine method which would allow me to
keep track of the stream position, but I'd like to know if there is a way to
avoid this.

Can anyone help?

Danny Smith
 
G

Guest

Danny
Since you are reading a line of text, you can keep track of how many characters you read. This will give you the position that you need. I haven't tried this myself, but it's worth a shot

Tu-Thac
www.ongtech.co

----- Danny Smith wrote: ----

Hi

I need to read a file and be able to

1. Find the current position in the strea
2. Have access to a handy ReadLine() method

Obviously the FileStream class supports random access, so you have a Seek(
method and a Position property to find the current stream position, and th
StreamReader class has a ReadLine() method. I thought using these togethe
would give me what I needed

StreamReader sr = new StreamReader( File.OpenRead( filename ) )
string line = sr.ReadLine()
long position = sr.BaseStream.Position

However, this does not work as the StreamReader has buffering which mean
the moment a Read call is made, much more than the single line is read fro
the BaseStream. Consequently the Position property does not return th
position *immediately* after the end of the line, which is what I need

This is possible in Java with the RandomAccessFile class, which support
methods for reading lines and seeking / obtaining the position. Is ther
are way to do this in C#

One option would be to write my own ReadLine method which would allow me t
keep track of the stream position, but I'd like to know if there is a way t
avoid this

Can anyone help

Danny Smit
 
S

Scott

Hi Danny,

I've created a class that parses a file of records that may handle your
need. It maintains a file position, gives you random access to the records,
and maintains a record count. Can you tell me more about what you're doing
with the file? Are you breaking each line into fields? Can I get a sample of
your file?

Scott
scott_ctr_@_modo_mail.com_ remove all the underscores to email me.
 
D

Danny Smith

The only problem with that is that you don't know how many new-line
characters there are. Either one or two, depending on the file format, but
ReadLine() just returns the line and not these characters.

Danny

Tu-Thach said:
Danny,
Since you are reading a line of text, you can keep track of how many
characters you read. This will give you the position that you need. I
haven't tried this myself, but it's worth a shot.
 
D

Danny Smith

Scott,

The file is a pdf file. Some of the file needs to be read as bytes as it is
not text, yet certain parts are more conveniently read as lines of text. I
would like to be able to:

1. Jump to a known position in the stream, position X
2. Read a line of text
3. Read some bytes.
4. Jump a few bytes back in the stream, position X + y.

The only unknown in this is the number new-line characters the line of text
has, but this means that I cannot work out the value of y.

Possibly I could read the line as bytes, then I would know exactly how many
bytes it was. I just wondered if there was a slightly easier way, as after
reading a line in Java you could query the stream for the exact position, so
I thought there may be something I'm unaware of in C#.

This would also be handy if you were reading in lines of text from a large
file (with an unknown number of lines) and you wanted to display a progress
bar showing how much of the file had been read. If you could get the
current position in the stream you could then calculate the percentage read
using the stream length. How would you do this?

Thanks,

Danny
 
G

Guest

You can get the length of the string you just read. Seek to that location, read 1 or 2 characters to determine whether it is \n or \r\n. Then, add the appropriate count to your length

Tu-Thac
www.ongtech.co

----- Danny Smith wrote: ----

The only problem with that is that you don't know how many new-lin
characters there are. Either one or two, depending on the file format, bu
ReadLine() just returns the line and not these characters

Dann

Tu-Thach said:
Danny
Since you are reading a line of text, you can keep track of how man
characters you read. This will give you the position that you need.
haven't tried this myself, but it's worth a shot
 
S

Scott

Unfortunately, my parser isn't up to this task either. Since you're mixing
binary and text, I think your best bet would be to derive your own class
from FileStream that adds a ReadLine method. You can look at the
implementation of StreamReader
(http://www.123aspx.com/rotor/rotorsrc.aspx?rot=42055) to help with
implementing the ReadLine method. This should be a fairly simple job.

Scott
 
D

Danny Smith

Scott,

That's exactly what I will do then! Thanks very much for that link - I
would not have known where to find that code!

Danny
 

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