为了账号安全,请及时绑定邮箱和手机立即绑定

从频繁更新的文件中读取

/ 猿问

从频繁更新的文件中读取

蝴蝶不菲 2019-09-21 11:21:44

我目前正在Linux系统上以python编写程序。目的是在发现特定字符串后读取日志文件并执行bash命令。日志文件正在被另一个程序不断写入。我的问题是:


如果我使用open()方法打开文件,我的Python文件对象是否会随着其他程序写入实际文件而更新,还是我必须按一定的时间间隔重新打开文件?


谢谢


吉姆


更新:感谢到目前为止的答案。我也许应该提到Java EE应用程序正在写入文件,因此我无法控制何时将数据写入文件。我目前有一个程序,该程序每10秒重新打开一次文件,并尝试从文件的最后读取位置读取字节。目前,它只是打印出返回的字符串。我希望不需要重新打开文件,但read命令将以某种方式可以访问Java应用程序写入文件的数据。


#!/usr/bin/python

import time


fileBytePos = 0

while True:

    inFile = open('./server.log','r')

    inFile.seek(fileBytePos)

    data = inFile.read()

    print data

    fileBytePos = inFile.tell()

    print fileBytePos

    inFile.close()

    time.sleep(10)

感谢您提供有关pyinotify和generators的技巧。我将看看这些以获得更好的解决方案。


查看完整描述

3 回答

?
慕丝7291255

我建议看一下David Beazley的Python生成器技巧,尤其是第5部分:处理无限数据。它将tail -f logfile实时处理与命令等效的Python 。


# follow.py

#

# Follow a file like tail -f.


import time

def follow(thefile):

    thefile.seek(0,2)

    while True:

        line = thefile.readline()

        if not line:

            time.sleep(0.1)

            continue

        yield line


if __name__ == '__main__':

    logfile = open("run/foo/access-log","r")

    loglines = follow(logfile)

    for line in loglines:

        print line,


查看完整回答
反对 回复 2019-09-21
?
慕慕0277861

“一个互动会话价值1000字”


>>> f1 = open("bla.txt", "wt")

>>> f2 = open("bla.txt", "rt")

>>> f1.write("bleh")

>>> f2.read()

''

>>> f1.flush()

>>> f2.read()

'bleh'

>>> f1.write("blargh")

>>> f1.flush()

>>> f2.read()

'blargh'

换句话说-是的,一个单一的“开放”就可以了。


查看完整回答
反对 回复 2019-09-21
?
阿波罗的战车

这是Jeff Bauer答案的略微修改版本,可抵抗文件截断。如果文件正在由处理非常有用logrotate。


import os

import time


def follow(name):

    current = open(name, "r")

    curino = os.fstat(current.fileno()).st_ino

    while True:

        while True:

            line = current.readline()

            if not line:

                break

            yield line


        try:

            if os.stat(name).st_ino != curino:

                new = open(name, "r")

                current.close()

                current = new

                curino = os.fstat(current.fileno()).st_ino

                continue

        except IOError:

            pass

        time.sleep(1)



if __name__ == '__main__':

    fname = "test.log"

    for l in follow(fname):

        print "LINE: {}".format(l)


查看完整回答
反对 回复 2019-09-21

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信