简体   繁体   English

连续读取python中日志文件的最后一行

[英]Continuously read the last line of log file in python

I have a file in which new lines are continuously written.我有一个文件,其中不断写入新行。

In python, I would like to continuously read the last line of this file, so that I can process the line.在 python 中,我想不断地读取这个文件的最后一行,以便处理该行。

I know there is the readlines() function but this is "static".我知道有readlines() function 但这是“静态的”。 If new lines are added after I called readlines() these new lines will not be read.如果在我调用readlines()之后添加了新行,则不会读取这些新行。

How can I do this in python?如何在 python 中执行此操作? Thanks谢谢

You will want to use a "state machine".您将需要使用“状态机”。 That is just a fancy way of saying, you want to keep track of where in the file you are, so you amy seek() to that position, read() to the end of file, and read and advance the current position everytime you encounter a newline.这只是一种花哨的说法,你想跟踪你在文件中的位置,所以你将seek()到那个 position, read()到文件末尾,每次你都读取并推进当前的 position遇到换行符。

You could use something like this, which could also be used like an iterator:你可以使用这样的东西,它也可以像迭代器一样使用:

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

You can also continuously check it for new lines by iterating again, like shown in the hypothetical example above, when baz is appended.当附加baz时,您还可以通过再次迭代来不断检查它是否有新行,如上面的假设示例所示。

Please note that, this way, every line must end with a linefeed ( \n ).请注意,这样一来,每一行都必须以换行符( \n结尾 This makes things simpler, and I suppose might be why it is the usual convention anyway.这使事情变得更简单,我想这可能就是为什么它是通常的约定。

This example takes a slightly more hands-on approach than just a simple readline loop like this one .这个例子比像这样一个简单的readline循环采用了一种更实际的方法。 I reckon it takes a bit more line-count this way.我认为这种方式需要更多的行数。 However, I believe it is cleaner for illustrative purposes;但是,我认为出于说明目的,它更清洁; I suppose it does a good enough job at explaining the basics of the task with simple object-oriented programming.我想它在用简单的面向对象编程来解释任务的基础方面做得很好。

PS I probably call seek a couple more times than I really need to. PS 我可能比我真正需要的多几次seek I could, for instance, not call it in the has() function, after each run of the for loop in __next__ .例如,在每次运行 __next__ 中的for循环之后,我可以不在has() __next__中调用它。 I decided to keep it this way, though, for illustrative clarity.不过,为了说明清楚起见,我决定保持这种方式。 :) :)

PPS I know it's not really what a state machine is. PPS 我知道这不是真正的 state 机器。 I mean in a very broad sense.我的意思是非常广泛的。 Actual finite state machines are an entirely different concept.实际的有限 state 机器是一个完全不同的概念。 All this does is increment a counter every time it encounters a new line.所有这一切都是在每次遇到新行时增加一个计数器。 I hope it's not too misleading, and that the actual point I was trying to make still remains clear – keeping track .我希望这不会太误导,并且我试图表达的实际观点仍然很清楚——保持跟踪

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM