读取

时间:2019-04-14 21:04:18

标签: python linux inotify file-monitoring

我正在从后面的一组文件(日志文件)中读取行,因为它们是使用pyinotify编写的。

我正在使用python本地方法打开和读取文件:

file = open(self.file_path, 'r')
# ... later
line = file.readline()

这通常是稳定的,可以处理正在删除和重新创建的文件。 pyinotify将通知取消链接和后续链接。

但是,某些日志文件并未被删除。而是将它们截断,并将新内容写入同一文件的开头。

我无法可靠地检测到何时发生,因为pyinotify仅会报告一次写入。我目前得到的唯一证据是pyinotify报告了写操作,而readline()返回了一个空字符串。但是,两次后续写入可能会触发相同的行为。

我曾考虑过将文件的大小与file.tell()进行比较,但是根据文档tell会产生一个不透明的数字,看来这不能相信是一个字节数。

有没有一种简单的方法可以检测到在读取文件时文件被截断了?


编辑:

可以使用简单的shell命令模拟截断文件:

echo hello > test.log
echo hello >> test.log
# Truncate test.log
echo goodbye > test.log

为此,可以使用一个简单的python脚本来确认文件被截断时file.tell()不会减少:

foo = open('./test.log', 'r')
line = foo.readline()
while line != '':
    print(foo.tell())
    print(line)
    line = foo.readline()

# Put a breakpoint on the following line and 
# truncate the file before it executes
print(foo.tell())

1 个答案:

答案 0 :(得分:1)

使用os.lseek(file.fileno(),0,os.SEEK_CUR)获得字节偏移量而不移动文件指针。您无法真正使用常规文件界面进行查找,这尤其重要,因为它可能包含了缓冲的文本(不再存在),而这些文本尚未被Python看到。如果文件不是字节流( eg ,Python 3中的默认open),它甚至可能位于多字节字符的中间,即使文件也无法继续立即超过您的文件偏移量。