我正在开发一个小型C#应用程序,它扫描日志文件中包含某些关键字的行,并在找到其中一个关键字时提醒用户。此日志可能非常大(几千兆字节,在最坏的情况下),但日志中与我相关的唯一行是在我的应用程序运行时添加到日志中的行。
有没有办法可以捕获附加到文件的每个文本行,而不必担心已经存在的文件内容?
我在搜索解决方案时已经发现了FileSystemWatcher类,虽然这似乎非常适合通知 我有新内容从日志中获取,但它似乎没有帮助告诉我添加了什么。
答案 0 :(得分:4)
如果在读取模式下保持FileStream打开(当然允许编写者),您应该能够最初扫描整个文件并在结束时等待,直到FSW通知您该文件已被修改。
如果文件被删除,请注意以某种方式重置读取线程,例如,如果您正在拖尾的日志文件被滚动。
在这里,我敲了一个示例 - 运行它,当它运行时,在记事本中编辑C:\Temp\Temp.txt
并保存它:
public static void Main()
{
var lockMe = new object();
using (var latch = new ManualResetEvent(true))
using (var fs = new FileStream(@"C:\Temp\Temp.txt", FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite))
using (var fsw = new FileSystemWatcher(@"C:\Temp\"))
{
fsw.Changed += (s, e) =>
{
lock (lockMe)
{
if (e.FullPath != @"C:\Temp\Temp.txt") return;
latch.Set();
}
};
using (var sr = new StreamReader(fs))
while (true)
{
latch.WaitOne();
lock (lockMe)
{
String line;
while ((line = sr.ReadLine()) != null)
Console.Out.WriteLine(line);
latch.Set();
}
}
}
}
答案 1 :(得分:0)
最有效的解决方案(如果您的应用程序需要它)是编写一个文件钩子驱动程序来捕获对该文件的所有写访问权。该驱动程序可能会告诉您更改了哪些字节。如果您不想用C / C ++编写驱动程序,也许可以使用EasyHook。 EasyHook非常棒,因为如果你知道写入日志文件的确切应用程序,你可以编写一个非常简单的用户模式钩子(在CodePlex上查看他的例子)。如果您不知道应用程序的名称,则可能必须编写一个内核挂钩(使用EasyHook更容易)。
答案 2 :(得分:0)
与this question类似,但您需要记录旧的文件大小。然后,不是寻找10个换行符,而是寻找尺寸差异。不过,你必须小心编码。
答案 3 :(得分:0)
不是从文件中读取文本(我假设你在做什么),而是读取文件的字节。如果您可以假设将始终追加对文件的写入,并且您知道文件的文本编码,那么您只需读取从原始文件的文件大小开始的字节。然后使用正确的编码将字节转换为文本。