我正在尝试实现一种简单的方法,以便在每次调用方法时从日志文件中读取新行。
我已经在stackoverflow(例如here)和其他地方查看了各种建议,以模拟“尾部”功能;大多数都涉及使用readline()
读取新行,因为它们被附加到文件中。它应该很简单,但无法使用包含的Python 2.6.1在OS X 10.6.4上正常工作。
为了解决问题的核心,我尝试了以下方法:
打开两个终端窗口。
在一个文件中,创建一个包含三行的文本文件“test.log”:
one
two
three
另一方面,启动python并执行以下代码:
Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.stat('test.log')
posix.stat_result(st_mode=33188, st_ino=23465217, st_dev=234881025L, st_nlink=1, st_uid=666, st_gid=20, st_size=14, st_atime=1281782739, st_mtime=1281782738, st_ctime=1281782738)
>>> log = open('test.log')
>>> log.tell()
0
>>> log.seek(0,2)
>>> log.tell()
14
>>>
我们看到tell()
seek(0,2)
将os.stat()
带到了one
two
three
four
five
报告的文件末尾,字节14。
在第一个shell中,将另外两行添加到“test.log”,使其如下所示:
>>> os.stat('test.log')
posix.stat_result(st_mode=33188, st_ino=23465260, st_dev=234881025L, st_nlink=1, st_uid=666, st_gid=20, st_size=24, st_atime=1281783089, st_mtime=1281783088, st_ctime=1281783088)
>>> log.seek(0,2)
>>> log.tell()
14
>>>
返回第二个shell,执行以下代码:
os.stat()
这里我们从{{1}}看到文件的大小现在是24个字节,但是寻找到文件的末尾仍然指向字节14?我在使用Python 2.5的Ubuntu上尝试过相同的操作,它可以像我期望的那样工作。我在Mac上尝试使用2.5,但得到的结果与2.6相同。
我必须遗漏一些基本的东西。有什么想法吗?
答案 0 :(得分:3)
如何在文件中再添加两行?
大多数文本编辑器都会经历如下操作:
fd = open(filename, read)
file_data = read(fd)
close(fd)
/* you edit your file, and save it */
unlink(filename)
fd = open(filename, write, create)
write(fd, file_data)
文件不同。 (用ls -li
检查;几乎每个文本编辑器的inode编号都会改变。)
如果您使用shell的>>
重定向将追加添加到日志文件中,它将完全按预期工作:
$ echo one >> test.log
$ echo two >> test.log
$ echo three >> test.log
$ ls -li test.log
671147 -rw-r--r-- 1 sarnold sarnold 14 2010-08-14 04:15 test.log
$ echo four >> test.log
$ ls -li test.log
671147 -rw-r--r-- 1 sarnold sarnold 19 2010-08-14 04:15 test.log
>>> log=open('test.log')
>>> log.tell()
0
>>> log.seek(0,2)
>>> log.tell()
19
$ echo five >> test.log
$ echo six >> test.log
>>> log.seek(0,2)
>>> log.tell()
28
请注意,tail(1)
命令具有-F
命令行选项,用于处理文件更改的情况,但存在同名文件。 (非常适合观看可能会定期轮换的日志文件。)
答案 1 :(得分:2)
简短回答:不,你的假设是。
您的文本编辑器正在创建一个具有相同名称的新文件,而不是修改旧文件。您可以在stat
结果中看到st_ino
不同。如果您要执行os.fstat(log.fileno())
,则会获得旧的st_ino
旧版本。
如果您想在tail
的实施中检查此问题,请定期比较st_ino
和stat
结果的fstat
。如果它们不同,则会有一个同名的新文件。