使用Python持续读取日志文件的最后一行

4
我有一个文件,其中不断写入新的行内容。
在Python中,我想要连续读取该文件的最后一行,以便可以处理该行内容。
我知道有readlines()函数,但这是“静态”的。如果在调用readlines()之后添加了新的行内容,则不会读取这些新的行内容。
如何在Python中实现此功能? 谢谢

这个回答解决了你的问题吗?从一个经常更新的文件中读取 - broAhmed
1个回答

0
你需要使用一个“状态机”。这只是一种花哨的说法,意思是你想要跟踪文件中的位置,所以你可以使用seek()到那个位置,read()到文件末尾,并且每次遇到换行符时读取并推进当前位置。
你可以使用类似于这样的东西,它也可以像迭代器一样使用:
import time


class LogFollower:
    def __init__(self, fp):
        self.position = 0
        self.fp = fp

    def seek(self):
        self.fp.seek(self.position)

    def has(self):
        self.seek()
        return '\n' in self.fp.read()

    def __iter__(self):
        while self.has():
            self.seek()
            line = self.fp.read().split('\n')[0]
            yield line

            # advance position - this is the 'state machine' part!
            self.position += len(line) + 1

follow = LogFollower(open("my_file.txt"))

# assume the file already has 2 lines

for line in follow:
    print(line)

#>foo
#>bar

time.sleep(5)

# now suppose a line 'baz' is added to the bottom
# somewhere during those 10 secs, then you decide
# to iterate again.

for line in follow:
    print(line)

#>baz

您也可以通过迭代方式不断检查新行,就像上面的假设性示例所示,在追加 baz 时。

请注意,这种方式下,每一行都必须以换行符(\n)结尾。这会让事情更简单,我想这可能是通常的习惯之所在。

这个示例采用的方法比 this one 中的简单 readline 循环要多一些亲力亲为。我认为这种方式需要更多的代码行数。然而,我相信它对于说明面向对象编程基础来说更加清晰易懂。

P.S. 我可能比实际需要的多调用了几次 seek 函数。例如,我可以在 __next__ 的每次运行后,在 for 循环中的每个运行之后,不在 has() 函数中调用它。但出于说明的清晰度,我决定保持现状。:)

P.P.S. 我知道这不是一个状态机的真正含义。我的意思是在非常广泛的意义上。实际的有限状态机是一个完全不同的概念。所有这个程序所做的就是每次遇到新行时递增计数器。我希望这不会太具有误导性,并且我试图表达的实际观点仍然保持清晰 - 跟踪

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接