【问题标题】:Continuously read the last line of log file in python在python中不断读取日志文件的最后一行
【发布时间】:2021-06-20 14:03:23
【问题描述】:

我有一个文件,其中不断写入新行。

在python中,我想不断地读取这个文件的最后一行,以便处理该行。

我知道有 readlines() 函数,但这是“静态的”。如果在我调用 readlines() 之后添加了新行,这些新行将不会被读取。

如何在 python 中做到这一点? 谢谢

【问题讨论】:

标签: python file


【解决方案1】:

您将需要使用“状态机”。这只是一种奇特的说法,你想跟踪你在文件中的位置,所以你把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 循环更实际一些。我认为这种方式需要更多的行数。但是,我认为出于说明目的,它更清洁;我想它在用简单的面向对象编程解释任务的基础方面做得很好。

附:我打电话给seek 的次数可能比我真正需要的要多。例如,在__next__ 中每次运行for 循环之后,我可以不在has() 函数中调用它。不过,为了说明清楚起见,我决定保持这种方式。 :)

附言我知道这并不是真正的状态机。我的意思是非常广泛的。实际的有限状态机是一个完全不同的概念。所有这一切都是在每次遇到新行时增加一个计数器。我希望这不会太误导,而且我试图表达的实际观点仍然很清楚——保持跟踪

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-26
    • 2012-06-24
    • 2021-06-22
    • 1970-01-01
    • 2018-02-25
    • 2021-04-21
    • 2023-03-03
    • 1970-01-01
    相关资源
    最近更新 更多