C# 追加和读取文本文件

C# 追加和读取文本文件,c#,C#,环境:欢迎任何.Net框架。 我有一个日志文件,可以全天候写入 我正在尝试创建一个应用程序,它将读取日志文件并处理数据 高效读取日志文件的最佳方法是什么?我想象用类似FileSystemWatcher的东西监视文件。但是,如何确保我的应用程序一旦处理了相同的数据,我就不会读取这些数据呢?或者说应用程序由于某种未知的原因而中止,它将如何恢复上次中断的位置 日志文件中的有效负载周围通常有一个页眉和页脚。也可能是内容中的id字段。但还不确定id字段是否存在 我还想象着,也许可以把阅读计数的行保存在某个

环境:欢迎任何.Net框架。 我有一个日志文件,可以全天候写入

我正在尝试创建一个应用程序,它将读取日志文件并处理数据

高效读取日志文件的最佳方法是什么?我想象用类似FileSystemWatcher的东西监视文件。但是,如何确保我的应用程序一旦处理了相同的数据,我就不会读取这些数据呢?或者说应用程序由于某种未知的原因而中止,它将如何恢复上次中断的位置

日志文件中的有效负载周围通常有一个页眉和页脚。也可能是内容中的id字段。但还不确定id字段是否存在


我还想象着,也许可以把阅读计数的行保存在某个地方,作为书签使用。

好吧,你必须自己为你的特殊情况找出你的魔力。如果您打算使用众所周知的文本编码,这可能是非常简单的想法。查看System.IO.StreamReader及其ReadLine()、DiscardBufferedData()方法和BaseStream属性。您应该能够记住文件中的最后一个位置,稍后将其倒带到该位置并再次开始读取,前提是您确定该文件只是附加的。还有其他的事情要考虑,并且没有一个普遍的答案。 作为一个简单的例子(您可能仍然需要进行大量调整以使其正常工作):


好吧,你必须自己为你的特殊情况想出你的魔法。如果您打算使用众所周知的文本编码,这可能是非常简单的想法。查看System.IO.StreamReader及其ReadLine()、DiscardBufferedData()方法和BaseStream属性。您应该能够记住文件中的最后一个位置,稍后将其倒带到该位置并再次开始读取,前提是您确定该文件只是附加的。还有其他的事情要考虑,并且没有一个普遍的答案。 作为一个简单的例子(您可能仍然需要进行大量调整以使其正常工作):


出于显而易见的原因,读取文件的全部内容以及从日志文件中删除行(在将它们加载到应用程序中之后)是不可能的


我认为部分解决方案是使用一个小型数据库(可能比完整的MySQL/MS SQL/PostgreSQL实例小得多),并用从日志文件读取的内容填充表。我非常确信,即使断电,然后机器再次启动,大多数关系数据库也应该能够轻松地恢复其状态。此解决方案需要一些可用于从日志文件中标识行的数据(例如:记录的操作的准确时间、操作发生的机器等)

出于明显的原因,读取文件的全部内容,以及从日志文件中删除行(在将行加载到应用程序中后)这是不可能的


我认为部分解决方案是使用一个小型数据库(可能比完整的MySQL/MS SQL/PostgreSQL实例小得多),并用从日志文件读取的内容填充表。我非常确信,即使断电,然后机器再次启动,大多数关系数据库也应该能够轻松地恢复其状态。此解决方案需要一些可用于从日志文件中标识行的数据(例如:记录的操作的确切时间、操作发生的机器等)

我想您会找到该文件。ReadLines(filename)函数与LINQ结合使用对于类似的事情非常方便。ReadAllLines()将以字符串[]数组的形式将整个文本文件加载到内存中,但ReadLines将允许您在遍历文件时立即开始枚举这些行。这不仅节省了您的时间,而且使内存使用率非常低,因为它一次只处理一行。使用语句很重要,因为如果此程序被中断,它将关闭刷新写入程序并将未写入内容保存到文件的文件流。然后,当它启动时,它将跳过所有已读取的文件

int readCount = File.ReadLines("readLogs.txt").Count();
using (FileStream readLogs = new FileStream("readLogs.txt", FileMode.Append))
using (StreamWriter writer = new StreamWriter(readLogs))
{
     IEnumerable<string> lines = File.ReadLines(bigLogFile.txt).Skip(readCount);
     foreach (string line in lines)
     {
         // do something with line or batch them if you need more than one
         writer.WriteLine(line);
     }
}
int readCount=File.ReadLines(“readLogs.txt”).Count();
使用(FileStream readLogs=newfilestream(“readLogs.txt”,FileMode.Append))
使用(StreamWriter=newstreamwriter(readLogs))
{
IEnumerable lines=File.ReadLines(bigLogFile.txt).Skip(readCount);
foreach(行中的字符串行)
{
//如果您需要不止一个,请使用生产线或批处理它们
writer.WriteLine(行);
}
}

正如MaciekTalaska所提到的,如果这是一个全天候写的东西,并且会变得相当大,我强烈建议使用数据库。文件系统根本不具备处理此类卷的能力,您将花费大量时间尝试发明解决方案,使数据库可以轻而易举地做到这一点。

我认为您会找到该文件。ReadLines(filename)函数与LINQ结合在一起对于类似的事情非常方便。ReadAllLines()将以字符串[]数组的形式将整个文本文件加载到内存中,但ReadLines将允许您在遍历文件时立即开始枚举这些行。这不仅节省了您的时间,而且使内存使用率非常低,因为它一次只处理一行。使用语句很重要,因为如果此程序被中断,它将关闭刷新写入程序并将未写入内容保存到文件的文件流。然后,当它启动时,它将跳过所有已读取的文件

int readCount = File.ReadLines("readLogs.txt").Count();
using (FileStream readLogs = new FileStream("readLogs.txt", FileMode.Append))
using (StreamWriter writer = new StreamWriter(readLogs))
{
     IEnumerable<string> lines = File.ReadLines(bigLogFile.txt).Skip(readCount);
     foreach (string line in lines)
     {
         // do something with line or batch them if you need more than one
         writer.WriteLine(line);
     }
}
int readCount=File.ReadLines(“readLogs.txt”).Count();
使用(FileStream readLogs=newfilestream(“readLogs.txt”,FileMode.Append))
使用(StreamWriter=newstreamwriter(readLogs))
{
IEnumerable lines=File.ReadLines(bigLogFile.txt).Skip(readCount);
foreach(行中的字符串行)
{
//做点什么