Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 动态读取文本文件上的更改#_C#_File_Text - Fatal编程技术网

C# 动态读取文本文件上的更改#

C# 动态读取文本文件上的更改#,c#,file,text,C#,File,Text,我有一个程序,它不断地将日志写入文本文件。 我没有它的源代码,所以我不能以任何方式修改它,它也受到Themida的保护 我需要读取日志文件并根据文件内容执行一些脚本。 我无法删除该文件,因为持续写入该文件的程序已锁定该文件。 那么,有什么更好的方法来读取文件并只读取文件的新行呢? 保存最后一行位置?或者在C#?中有什么有用的方法来解决这个问题吗?也许在打开文件时使用FileShare(因为它正被另一个进程使用)。Hans Passant为这一部分提供了一个很好的答案: 看看这一点和公认的答案,这

我有一个程序,它不断地将日志写入文本文件。 我没有它的源代码,所以我不能以任何方式修改它,它也受到Themida的保护

我需要读取日志文件并根据文件内容执行一些脚本。 我无法删除该文件,因为持续写入该文件的程序已锁定该文件。 那么,有什么更好的方法来读取文件并只读取文件的新行呢? 保存最后一行位置?或者在C#?

中有什么有用的方法来解决这个问题吗?也许在打开文件时使用FileShare(因为它正被另一个进程使用)。Hans Passant为这一部分提供了一个很好的答案:

看看这一点和公认的答案,这可能也会有所帮助

using (var fs = new FileStream("test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
using (var reader = new StreamReader(fs))
{
    while (true)
    {
        var line = reader.ReadLine();

        if (!String.IsNullOrWhiteSpace(line))
            Console.WriteLine("Line read: " + line);
    }
}
我测试了上面的代码,如果您试图一次读取一行代码,它就可以工作。唯一的问题是,如果在完成写入之前将该行刷新到文件中,那么您将分多个部分读取该行。只要日志系统一次写入每一行,就应该可以了


如果没有,那么您可能希望读入缓冲区而不是使用ReadLine,这样您就可以通过检测每个Environment.NewLine子字符串来自己解析缓冲区。

您可以在一个紧密的循环中继续调用ReadToEnd()。即使在到达文件末尾后,它也只会返回一个空字符串“”。如果文件中写入了更多数据,它将在后续调用中提取这些数据

while (true)
{
    string moreData = streamReader.ReadToEnd();
    Thread.Sleep(100);
}

请记住,您可能会以这种方式阅读部分行。另外,如果您正在处理非常大的文件,您可能需要另一种方法。

使用filesystemwatcher检测更改,并使用上次读取位置获取新行并查找文件

日志文件正在“持续”更新,因此您确实不应该在每次文件更改时使用引发事件。这将持续触发,并且你已经知道它将非常频繁地改变

我建议使用计时器事件定期处理文件。对于使用
System.Threading.Timer
1的良好模式。保持文件流处于打开状态以便读取,或每次重新打开文件流,直到上次成功读取的结束位置。“上次成功读取”的意思是,您应该封装完整日志行的读取和验证。成功读取并验证日志行后,您就有了下一次
搜索的新位置


1请注意,
System.Threading.Timer
将在系统提供的线程上执行,该线程由。对于短任务,这比一个专用线程更可取。

在另一篇文章中使用此答案

这是一个非常有效的方法,它每秒检查一次文件大小是否已更改。因此,文件通常不会因此而被读取锁定


其他答案非常有效和简单。他们中的一些人会连续读取锁定文件,但这对大多数人来说可能不是问题。

与此相关的是一个很好的答案,非常简单。我的更好只是因为文件大部分时间没有被读锁定。这也是一个好的答案,它会一直等到完整的行可用,但它会持续锁定文件(这不一定是个问题)。这里的一个补充是,如果行==NullOrWhiteSpace,则会添加一点睡眠。您能更详细地介绍一下吗?我或多或少也有同样的问题。我有一个大文件(60MB),它一直是从机器上写的。现在我应该读所有写在里面的数据。我是否可以不时删除该文件?
while (true)
{
    string moreData = streamReader.ReadToEnd();
    Thread.Sleep(100);
}