我正在尝试显示添加到文件中的新行。
所以假设我有一个sample_file.txt
:
1. line 1
2. line 2
3. line 3
我想检查这个文件是否有新行,然后显示该行(不再打印所有文件)
#!/usr/bin/python
import os
import pyinotify
from datetime import datetime
import time
PATH = os.path.join(os.path.expanduser('~/'), 'sample_file.txt')
m = pyinotify.WatchManager()
m.add_watch(PATH, pyinotify.ALL_EVENTS, rec=True)
notifier = pyinotify.Notifier(m, pyinotify.ProcessEvent(), 0, 0, 100)
f = open(PATH)
for line in f.readlines():
print line
while True:
time.sleep(5)
try:
if notifier.check_events():
# RIGHT HERE:
# HOW TO DO SOMETHING LIKE
# f.last() ???
print f.next()
else:
print 'waiting for a line....'
except KeyboardInterrupt:
notifier.stop()
break
我想的是在循环之前读取所有行,然后打印下一行,但是我的代码出错了,它在循环后立即检查f.next()
。 / p>
答案 0 :(得分:4)
我将解决这两个问题:
tail
pyinotify
模块。在您的代码中,您需要:
read
或readlines
,seek
进行打印。例如转换为:
f = open(PATH)
for line in f.readlines():
print line[:-1]
while True:
time.sleep(5)
try:
line_start = f.tell()
new_lines = f.read()
last_n = new_lines.rfind('\n')
if last_n >= 0:
# We got at least one full line
line_start += last_n + 1
print new_lines[:last_n]
else:
# No complete line yet
print 'no line'
f.seek(line_start)
except KeyboardInterrupt:
notifier.stop()
break
你可以在这里找到更多的例子,虽然有些例子没有解决文件中没有以换行符结尾的内容:
这里有一些替代方案How can I tail a log file in Python?
您还应该按照文档中的说明在pyinotify
的事件处理程序中移动代码。
check_events
会返回True
,但它实际上并不会处理事件,所以在事件处理完毕之前,它总是会返回True
。 / p>
另外,请尝试避免while
/ sleep
循环。 Inotify增加了在接收事件时处理事件的功能,而不会影响资源。 while
/ sleep
循环的反应性会降低。
以下是pyinotify
上Short Tutorial的两个第一种方法。
如果您没有其他事件循环,这是首选方法,因为它将是最具反应性的:
PATH = os.path.join(os.path.expanduser('~/'), 'experiments', 'testfile')
class EventHandler(pyinotify.ProcessEvent):
def __init__(self, *args, **kwargs):
super(EventHandler, self).__init__(*args, **kwargs)
self.file = open(PATH)
self.position = 0
self.print_lines()
def process_IN_MODIFY(self, event):
print 'event received'
self.print_lines()
def print_lines(self):
new_lines = self.file.read()
last_n = new_lines.rfind('\n')
if last_n >= 0:
self.position += last_n + 1
print new_lines[:last_n]
else:
print 'no line'
self.file.seek(self.position)
wm = pyinotify.WatchManager()
handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler)
wm.add_watch(PATH, pyinotify.IN_MODIFY, rec=True)
notifier.loop()
如果您已经有一个处理循环,那么只需定期调用process_events
即可。 EventHandler
类与方法1中的相同,但现在不是调用notifier.loop()
,而是向通知程序添加一个小超时,并实现我们自己的事件循环。
...
wm = pyinotify.WatchManager()
handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler, timeout=10)
wm.add_watch(PATH, pyinotify.IN_MODIFY, rec=True)
while True:
# Do something unrelated to pyinotify
time.sleep(5)
notifier.process_events()
#loop in case more events appear while we are processing
while notifier.check_events():
notifier.read_events()
notifier.process_events()