I'm looking to create a console application that will read a file, and monitor every new line since it's being write by another process every .5 seconds.
How can I achieve that, within a Console App using .NET 4.5?
I'm looking to create a console application that will read a file, and monitor every new line since it's being write by another process every .5 seconds.
How can I achieve that, within a Console App using .NET 4.5?
As @Sudhakar mentioned, FileSystemWatcher is useful when you want to be notified when a file updates sporadically, and polling at regular intervals is useful when you want to be constantly processing information from an always-growing file (such as a busy log file).
I'd like to add a note about efficiency. If you are concerned with the efficiency and speed of processing large files (many MB or GB), then you will want to track your position in the file as you read and process updates. For example:
// This does exactly what it looks like.
long position = GetMyLastReadPosition();
using (var file = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
if (position == file.Length)
return;
logFile.Position = position;
using (var reader = new StreamReader(file))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// Do reading.
}
position = file.Position; // Store this somewhere too.
}
}
This should allow you to avoid reprocessing any part of a file that you have already processed.
It sounds like you want a version of tail for Windows. See "Looking for a windows equivalent of the unix tail command" for discussion on that.
Otherwise, open the file without preventing other processes access using FileShare.ReadWrite. Seek to the end read then use Thread.Sleep() or Task.Delay() to wait the half a second between seeing if there are any changes.
For example:
public static void Follow(string path)
{
// Note the FileShare.ReadWrite, allowing others to modify the file
using (FileStream fileStream = File.Open(path, FileMode.Open,
FileAccess.Read, FileShare.ReadWrite))
{
fileStream.Seek(0, SeekOrigin.End);
using (StreamReader streamReader = new StreamReader(fileStream))
{
for (;;)
{
// Substitute a different timespan if required.
Thread.Sleep(TimeSpan.FromSeconds(0.5));
// Write the output to the screen or do something different.
// If you want newlines, search the return value of "ReadToEnd"
// for Environment.NewLine.
Console.Out.Write(streamReader.ReadToEnd());
}
}
}
}
Solution 1: You can use FileSystemWatcher
class
From MSDN:
Use FileSystemWatcher to watch for changes in a specified directory. You can watch for changes in files and subdirectories of the specified directory. You can create a component to watch files on a local computer, a network drive, or a remote computer.
Solution 2: You can use Polling
by creating a Timer
and reading the contents of the file for every 5 seconds.