监视文件是否停止在python

时间:2015-07-11 15:28:42

标签: python file timestamp

我有一个程序,每秒都在写一个文件。文件写入发生在与UI并行的线程中。由于某些硬件问题,它有时会停止写一天。我想检查文件是否停止写入,如果没有更新,则重新启动程序。我想查看文件的时间戳,看看它是否没有得到更新(并且不想看门狗等等。因为我只是在文件停止写入时才需要。)

try:
    if time.time()>(os.stat(filename).st_mtime+2):
        raise ValueError("Yikes! Spike")
except ValueError:
    with open('errors.log','a') as log:
        log.write('Spike occured at '+ time.strftime(
        "%H:%M:%S")+' on '+datetime.date.today().strftime('%d/%m/%Y')+'\n')
        log.close()
    restart_program()

此块每秒运行一次。但这种情况适得其反,当应用程序关闭以重新启动时,它会每秒关闭并且不会再次启动。我每秒都会收到异常消息。我尝试增加时差,但这并没有帮助。

接下来我试了

ftimestamp = os.stat(filename).st_mtime
try:
    if os.stat(filename).st_mtime>=ftimestamp:
        ftimestamp = time.time()
        print "ftimestamp updated and all is well"
    else:
        ftimestamp = os.stat(filename).st_mtime
        raise ValueError("Yikes! Spike!")
        print "file time is behind"
except ValueError:
    with open('errors.log','a') as log:
        log.write('Spike occured at '+ time.strftime(
        "%H:%M:%S")+' on '+datetime.date.today().strftime('%d/%m/%Y')+'\n')
        log.close()
    restart_program()

我尝试更新变量" ftimestamp"到当前时间" time.time()"因为下一次比较只在一秒后发生,我希望文件时间高于前一次比较。 (该块每秒通过wx.CallLater函数运行。)

我的程序仍然失败......我无法理解我哪里出错......有人请帮帮忙!或者有一种方法可以简单地检查文件是否停止写入?

3 个答案:

答案 0 :(得分:2)

我们可以通过执行以下操作来尝试检查文件大小的变化作为可能的解决方案:

import os
from time import sleep
# other imports

while True:
    file1 = os.stat('file.txt') # initial file size
    file1_size = file1.st_size

    # your script here that collects and writes data (increase file size)
    sleep(1)
    file2 = os.stat('file.txt') # updated file size
    file2_size = file2.st_size
    comp = file2_size - file1_size # compares sizes
    if comp == 0:
        restart_program()
    else:
        sleep(5)

您可能需要相应地调整sleep()函数这些只是我正在使用的估计,因为我无法测试您的实际代码。最后,这是无限循环,只要您希望脚本继续编写,它就会一直运行。

另一种解决方案是将您的文件更新为:

import os
import sys
from time import sleep
# other imports

while True:
    file1 = os.stat('file.txt') # initial file size
    file1_size = file1.st_size

    # your script here that collects and writes data (increase file size)
    sleep(1)
    file2 = os.stat('file.txt') # updated file size
    file2_size = file2.st_size
    comp = file2_size - file1_size # compares sizes
    if comp == 0:
        sys.exit
    else:
        sleep(5)

然后使用辅助程序来运行您的脚本:

import os
from time import sleep, strftime

while True:
    print(strftime("%H:%M:%S), "Starting"))
    system('main.py') # this is another infinite loop that will keep your script running
    print(strftime("%H:%M:%S), "Crashed"))
    sleep(5)

答案 1 :(得分:1)

要确定文件是否在GUI程序中按时更改,您可以使用标准工具进行事件循环,每隔一秒钟运行一次函数,例如,在tkinter中如何执行此操作:

#!/usr/bin/env python3
import logging
import os
import sys
import tkinter
from datetime import datetime
from time import monotonic as timer, localtime

path = sys.argv[1]
interval = 120 # check every 2 minutes

def check(last=[None]):
    mtime = os.path.getmtime(path) # or os.path.getsize(path)
    logging.debug("mtime %s", datetime.fromtimestamp(mtime))
    if last[0] == mtime: #NOTE: it is always False on the first run
        logging.error("file metadata hasn't been updated, exiting..")
        root.destroy() # exit GUI
    else: # schedule the next run
        last[0] = mtime
        root.after(round(1000 * (interval - timer() % interval)), check)


logging.basicConfig(level=logging.DEBUG,
                    filename=os.path.splitext(__file__)[0] + ".log",
                    format="%(asctime)-15s %(message)s", datefmt="%F %T")
root = tkinter.Tk()
root.withdraw() # hide GUI
root.after(round(1000 * (interval - timer() % interval)), check) # start on boundary
root.mainloop()

您可以使用supervisord,systemd或upstart等自动重新生成脚本。

请参阅How to run a function periodically in python

答案 2 :(得分:1)

最后,在修改了基于时间戳的选项后,以下内容似乎对我有用。

try:
    if time.time()-os.stat(filename).st_mtime>6:
        touch(filename)
        raise ValueError("Yikes! Spike")
except ValueError:
    with open('errors.log','a') as log:
        log.write('Spike/App restarting occured at '+ time.strftime(
                "%H:%M:%S")+' on '+datetime.date.today().strftime('%d/%m/%Y')+'\n')
        log.close()
    restart_program()

早些时候,问题是它会检测到文件在给定的时间间隔内停止写入并继续满足相同的时间。

time.time()-os.stat(filename).st_mtime>6 

但是一旦满足此条件,除非更新文件时间戳,否则它将继续满足此条件并将继续重新启动程序。现在在我的解决方案中,我'触摸'文件一次(touch used from here)满足条件,现在它按预期工作。

感谢大家的投入。