我可以以阻塞方式使用file.readline吗?我这样做对吗?

0 投票
2 回答
1002 浏览
提问于 2025-04-17 00:56

我正在尝试写一个程序,用来监控一个日志文件,当它看到一整行内容时,就给这行加上时间戳:

import sys

f = open(sys.argv[1])
if not f:
    print 'Failed to open %s' % sys.argv[1]

print sys.argv[1]

import time

try:
    while True:
        line = f.readline().replace('\n', '')
        if not line:
            continue
        print time.time(), line
except KeyboardInterrupt:
    pass

f.close()

我之所以要检查行的内容,是因为让我惊讶的是,readlines 这个方法并不会阻塞,也就是说,它会立即返回一个空字符串,表示文件已经读到头了。

所以,关于监控文件,我有几个问题:有没有办法让我这个程序在读取时阻塞?我在这个循环中看到空字符串,这是否意味着它们实际上并不代表行的结束?如果文件仍然在写入中,是否会在文件中添加行结束符?

2 个回答

2

你可以使用一个叫做 subprocess 的工具来打开类似于 tail 的程序,并读取它的输出,这个过程会让程序暂停,直到有新的内容出现。比如,这里有一个简单的 Python 代码示例,展示了如何实现这个功能。

import time
from subprocess import Popen, PIPE
file_path = '/home/auniyal/src/main/app.log'
p = Popen(['tail', '-f', file_path], stdout=PIPE)

while True:
    line = p.stdout.readline()
    print time.time(),"Wow",line
2
  1. os.path.getsize 来检查文件大小,看看文件有没有变化。
  2. 只有在文件大小有变化时,才用 f.readline 来读取内容。
  3. 每次读取之前,先调用 seek,确保你是从文件的最后一行开始读取。
  4. f.readline()[0:-1] 来去掉行末的 \n(感谢rm提醒,使用 rstrip 可能会遇到问题)。
  5. 与其不停地运行这个循环,不如每秒测试一次,并使用 sleep(相信我,你的电脑会感激你的)。

撰写回答