我正在寻找一个能够读取文件的控制台应用程序,并监视每一个新行,因为它每隔0.5秒被另一个进程写入。
如何在使用.NET 4.5的控制台应用程序中实现这一目标?
答案 0 :(得分:4)
听起来你想要一个适用于Windows的尾部版本。有关该问题的讨论,请参阅“Looking for a windows equivalent of the unix tail command”。
否则,open the file不会阻止其他进程使用FileShare.ReadWrite进行访问。寻找到最后阅读,然后使用Thread.Sleep()或Task.Delay()等待半秒,看看是否有任何变化。
例如:
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());
}
}
}
}
答案 1 :(得分:3)
正如@Sudhakar所提到的,当您希望在文件偶尔更新时收到通知时,FileSystemWatcher很有用,并且当您希望不断处理来自不断增长的文件(例如繁忙日志)的信息时,定期轮询很有用文件)。
我想补充说明效率。如果您关心处理大文件(许多MB或GB)的效率和速度,那么您将需要在阅读和处理更新时跟踪文件中的位置。例如:
// 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.
}
}
这样可以避免重新处理已经处理过的文件的任何部分。
答案 2 :(得分:2)
解决方案1:您可以使用FileSystemWatcher
类
来自MSDN:
使用FileSystemWatcher监视指定目录中的更改。 您可以查看指定文件和子目录的更改 目录。您可以创建一个组件来监视本地文件 计算机,网络驱动器或远程计算机。
解决方案2 :您可以通过创建Polling
并每5秒读取一次文件内容来使用Timer
。