在Python中读取正在写入的打开文件句柄
我知道这是流处理中的一个经典问题,但我不知道在Python中该怎么处理。我有一个文件句柄,它正在被一个活跃的进程写入。我想逐行读取这个文件句柄中的内容,但我不想因为等待读取而导致程序卡住。我会一直读取,直到文件结束(EOF)或者循环读取60秒,以先到者为准。如果有人能给我一些建议,我会非常感激。下面是我对这个问题的伪代码描述。
proc = genprocess("command")
found_a = False
found_b = False
start = time.time()
while True:
line = proc.readline()
while line:
if not found_a and grep(pattern_a, line):
found_a = True
print "Found A, now looking for B"
elif not found_b and grep(pattern_b, line):
found_b = True
print "Found B, all done"
break
if time.time() - start > 60:
break
else:
time.sleep(5)
proc.kill()
问题在于,这段代码每次只读取一行。我希望循环内部能够尽可能多地迭代,但不要因为等待新内容写入文件而卡住。一旦读取到的内容足够多,它应该暂停5秒,以便让更多内容积累。
2 个回答
1
上面提到的关于fcntl的例子还不错(除了它让程序一直在忙着循环检查),不过我最后还是用了“select”来实现差不多想要的功能。
started = False
while True:
if (time.time() - start > wait_for) or started:
break
(rlist, wlist, xlist) = select([proc.stdout], [], [], wait_interval)
if len(rlist) > 0:
line = rlist[0].readline() # read one line (this blocks until '\n' is read)
else: # nothing available to read from proc.stdout
print ".",
sys.stdout.flush()
time.sleep(1)
continue
if re.search("daemon started", line):
started = True
if not started:
proc.kill() # don't leave the process running if it didn't start properly
如果用户可能会按CTRL-C来中断这个操作,那么把整个过程放在一个try/except块里,并且监测KeyboardInterrupt,这样就可以调用proc.kill()来结束进程,而不是让它在后台继续运行。