一尘不染

C#连续读取文件

c#

我想像带有“ -f”参数的GNU尾部一样连续读取文件。我需要它来实时读取日志文件。正确的做法是什么?


阅读 442

收藏
2020-05-19

共1个答案

一尘不染

您要以FileStream二进制模式打开。定期查找文件的末尾减去1024个字节(或其他任何字节),然后读取到末尾并输出。就是这样tail -f

您的问题的答案:

二进制文件,因为如果您以文本形式读取文件,则很难随机访问该文件。您必须自己进行二进制到文本的转换,但这并不困难。(见下文)

1024字节,因为它是一个非常方便的数字,并且应处理10或15行文本。通常。

这是打开文件,读取最后1024个字节并将其转换为文本的示例:

static void ReadTail(string filename)
{
    using (FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
        // Seek 1024 bytes from the end of the file
        fs.Seek(-1024, SeekOrigin.End);
        // read 1024 bytes
        byte[] bytes = new byte[1024];
        fs.Read(bytes, 0, 1024);
        // Convert bytes to string
        string s = Encoding.Default.GetString(bytes);
        // or string s = Encoding.UTF8.GetString(bytes);
        // and output to console
        Console.WriteLine(s);
    }
}

请注意,您必须使用来打开FileShare.ReadWrite,因为您正试图读取当前已打开的文件,以供其他进程进行写入。

另请注意,我使用Encoding.Default,这在美国/英语和大多数西欧语言中将是8位字符编码。如果文件是以其他某种编码(例如UTF-8或其他Unicode编码)编写的,则字节可能无法正确转换为字符。如果您认为这将是一个问题,则必须通过确定编码来解决。搜索堆栈溢出以获取有关确定文件的文本编码的信息。

如果要定期执行此操作(例如,每15秒执行一次),则可以设置一个计时器,该计时器可以根据需要多次调用该ReadTail方法。您可以通过在程序启动时仅打开一次文件来稍微优化一下。随你(由你决定。

2020-05-19