question

DavidStone-5530 avatar image
0 Votes"
DavidStone-5530 asked DavidStone-5530 commented

C# Help with positioning a reader.StreamReader record number

I am new to C#, but have programmed in another language (RPG) for 40 years.

I've written a program to read an error log file, searching for certain keywords (errors) that we need notification on. When I reach end of file, I want the program to go to sleep for a period time, then wake up and resume reading the file from where I left off.

In RPG, there are a number of op codes and processes that I would use (in this case, it would be reading the file by relative record number) where I would save the last RRN I read, sleep and then start at the next RRN from where I left off. I would repeat this process until the program is sent a termination code or if a new day starts (after midnight).

How do I accomplish this in C# using either StreamReader or some other process? I tried reader.BaseStream.Position, passing it a line number from the previous read statement, but that doesn't do what I expect. Help would be appreciated.

dotnet-csharp
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

There is no easy way. I might write something later but I am sure others will have suggestions that will work well enough. Note that record number works only if the records are fixed in length but that is a strange concept for young people. I am not a RPG programmer but I did use COBOL earlier in my career.

0 Votes 0 ·

1 Answer

Viorel-1 avatar image
0 Votes"
Viorel-1 answered DavidStone-5530 commented

Try something like this:

 string path = @"C:\LogFile.log";
 long last_position = 0;
    
 using( var fs = new FileStream( path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ) )
 {
    fs.Position = last_position;
    
    using( var sr = new StreamReader( fs ) )
    {
       for(; ; )
       {
          last_position = sr.BaseStream.Length;
          string line = sr.ReadLine( );
          if( line == null ) break;
          // process the line
          // . . .
       }
    }
 }

Keep the value of last_position and use it next time instead of zero.


· 7
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I tried using BaseStream.Length and it did not work so I did research. The Stream.Length property is the current position in the buffer but not the current position of the StreamReader. There is much discussion of the issue. I think that one possibility (for here) is to use Stream to read from a specified position (zero initially) to the end then put that into a StringReader then use that starting position plus the new size to seek the next time.


0 Votes 0 ·

The Stream.Length property is the length of the stream (file).


0 Votes 0 ·

This worked perfectly! I was getting hung up on a physical record number, as opposed to the actual string length of the streamfile. This does make sense to me, even with my limited knowledge of C#. THANK YOU for a simple and very functional answer!

0 Votes 0 ·

Well if it happens that it does not work then I have another possibility that is likely to work. Are you sure you are not losing data using that solution?

0 Votes 0 ·

I don't appear to be losing anything, but I'm going to do more extensive testing to make sure it's working as expected.

0 Votes 0 ·
Show more comments

I've extensively tested this solution and it works without issue. Thank you for your assistance.

0 Votes 0 ·