【发布时间】:2014-04-26 02:56:36
【问题描述】:
我正在寻找创建一个控制台应用程序,它将读取一个文件,并监视每个新行,因为它每 0.5 秒被另一个进程写入一次。
如何在使用 .NET 4.5 的控制台应用程序中实现这一点?
【问题讨论】:
标签: c# .net console-application filestream
我正在寻找创建一个控制台应用程序,它将读取一个文件,并监视每个新行,因为它每 0.5 秒被另一个进程写入一次。
如何在使用 .NET 4.5 的控制台应用程序中实现这一点?
【问题讨论】:
标签: c# .net console-application filestream
听起来您想要一个适用于 Windows 的 tail 版本。请参阅“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());
}
}
}
}
【讨论】:
正如@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;
file.Position = position;
using (var reader = new StreamReader(file))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// Do reading.
}
position = file.Position; // Store this somewhere too.
}
}
这应该允许您避免重新处理您已经处理过的文件的任何部分。
【讨论】:
解决方案一:你可以使用FileSystemWatcher类
来自 MSDN:
使用 FileSystemWatcher 监视指定目录中的更改。 您可以观察指定的文件和子目录的变化 目录。您可以创建一个组件来监视本地文件 计算机、网络驱动器或远程计算机。
解决方案 2:您可以通过创建 Timer 并每 5 秒读取文件内容来使用 Polling。
【讨论】: