C # - The most efficient way to periodically read the last part of a file

I want to periodically read a log file, which is also written. The program will periodically read the contents of the log file and analyze it to extract some values. But I do not want to read the whole file every time.

Is there a way to read a file from a specific line?

For example, on first reading, the file has 100 lines. I mark this value, and the next time I read it, I start reading from line 100 and save the line number of the current file.

Is there an effective way to do this? The log file will grow to about 100 MB, and I will need to read every 5 seconds. Thus, it would be inefficient to read the complete file every time.

Any suggestion is much appreciated.

+5
source share
4

, , , . : MSDN

using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read))
{
    fs.Seek(offset, SeekOrigin.End);
}

filestream , , "", .

+3

, . , , .

var fs = new FileStream(path,FileMode.Open,FileAccess.Read, FileShare.ReadWrite);
+2

- , . - , , (numBytes):

cmdLogReader = new System.IO.StreamReader(cmdLogFileIn);

if (cmdLogReader.BaseStream.Length < (numBytes - 1)) {
    return cmdLogReader.ReadToEnd;
} else {
    cmdLogReader.BaseStream.Seek(-numBytes, System.IO.SeekOrigin.End);
    cmdLogReader.ReadLine();
    return cmdLogReader.ReadToEnd;         
} 

BaseStream.Length , , ( : numBytes BaseStream.Length - previousBaseStreamLength - ), , .

You may have to skip the call ReadLineif you do this, since it is really only there to go to the nearest line after returning a random amount. If you know that you are going to land at the boundary of the line, you can simply ReadToEnd.

This is a bit complicated implementation, but very fast, which is why I use it.

+1
source

A lawsuit can do it well. But I want to provide another way forward.

    public static void Read()
    {
        var fs = new FileStream(@"G:\test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        int lastReadCount = 0;
        while (true)
        {
            var totalCountOfFile = fs.Length;
            if (lastReadCount < totalCountOfFile)
            {
                var buffer = new byte[1024];
                int count = fs.Read(buffer, 0, buffer.Length);
                lastReadCount += count;
                Display(buffer);
            }
            Thread.Sleep(5000);
        }
    }

    private static void Display(byte[] buffer)
    {
        var text = Encoding.UTF8.GetString(buffer.Where(p=>p != 0).ToArray());
        Console.Write(text);
    }
+1
source

All Articles