我想像带有“ -f”参数的GNU尾部一样连续读取文件。我需要它来实时读取日志文件。正确的做法是什么?
您要以FileStream二进制模式打开。定期查找文件的末尾减去1024个字节(或其他任何字节),然后读取到末尾并输出。就是这样tail -f。
FileStream
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,因为您正试图读取当前已打开的文件,以供其他进程进行写入。
FileShare.ReadWrite
另请注意,我使用Encoding.Default,这在美国/英语和大多数西欧语言中将是8位字符编码。如果文件是以其他某种编码(例如UTF-8或其他Unicode编码)编写的,则字节可能无法正确转换为字符。如果您认为这将是一个问题,则必须通过确定编码来解决。搜索堆栈溢出以获取有关确定文件的文本编码的信息。
Encoding.Default
如果要定期执行此操作(例如,每15秒执行一次),则可以设置一个计时器,该计时器可以根据需要多次调用该ReadTail方法。您可以通过在程序启动时仅打开一次文件来稍微优化一下。随你(由你决定。
ReadTail