I was trying to parse a file which was divided into numerous parts - each one 12 lines long. For debugging, I was interested in how fast the file was being read and processed and therefore looked at the StreamReader.BaseStream.Position property. Here is an example of what I was trying to do:
class Program
{
static void Main(string[] args)
{
string filename = @"C:\windows\windowsupdate.log";
string filenameBackup = filename + ".bac";
File.Copy(filename, filenameBackup);
FileStream fs = new FileStream(filenameBackup, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs);
int lineNumber = 0;
while (!sr.EndOfStream)
{
Console.WriteLine("Lines Read = {0}, Position = {1}", lineNumber, sr.BaseStream.Position);
string[] lines = ReadXLines(sr,5);
lineNumber += lines.Length;
}
Console.Read();
}
private static string[] ReadXLines(StreamReader sr, int linesToRead)
{
string[] lines = new string[linesToRead];
for (int lineNumber = 0; lineNumber < lines.Length; lineNumber++)
{
lines[lineNumber] = sr.ReadLine();
}
return lines;
}
}
Now, the output on my computer was this:
Lines Read = 0, Position = 1024
Lines Read = 5, Position = 1024
Lines Read = 10, Position = 1024
Lines Read = 15, Position = 2048
Lines Read = 20, Position = 2048
Lines Read = 25, Position = 3072
Lines Read = 30, Position = 3072
Lines Read = 35, Position = 4096
Lines Read = 40, Position = 5120
Lines Read = 45, Position = 5120
Lines Read = 50, Position = 6144
Lines Read = 55, Position = 7168
Lines Read = 60, Position = 7168
Lines Read = 65, Position = 8192
Lines Read = 70, Position = 8192
Lines Read = 75, Position = 9216
Lines Read = 80, Position = 9216
Lines Read = 85, Position = 10240
Lines Read = 90, Position = 10240
Lines Read = 95, Position = 11264
Lines Read = 100, Position = 11264
Lines Read = 105, Position = 12288
......
What is odd about this sequence is that the position of the FileStream is already at 1024 before anything has been read! Also, the 1024 position stays the same for 2 reads. Why is this?
The StreamReader class is a buffered reader. Therefore, it is reading the stream before anything is processed and when reading directly from StreamReader, if the amount read does not extract the entire buffer, then the position of the underlying stream doesn't change.
Unfortunately, there is nothing you can do about this. Therefore the only 2 ways you can keep track of the position is to:
- Count how many characters are in each line (plus the
Environment.Newline) and total up the position line by line.
- Create your own implementation of the
FileStream, which has a ReadLine() method. This method should continue to read the Stream until Environment.Newline is encountered. Remember, Environment.Newline is not included in the string returned.