【问题标题】:Is Python's seek() on OS X broken?OS X 上的 Python 的 seek() 是否损坏?
【发布时间】:2010-08-14 11:06:21
【问题描述】:

我正在尝试实现一个简单的方法,以便在每次调用该方法时从日志文件中读取新行。

我查看了有关 stackoverflow(例如 here)和其他地方的各种建议,用于模拟“尾部”功能;大多数涉及使用readline() 在新行附加到文件时读取它们。它应该足够简单,但不能让它在 OS X 10.6.4 和包含的 Python 2.6.1 上正常工作。

为了解决问题的核心,我尝试了以下方法:

  1. 打开两个终端窗口。

  2. 在一个中,创建一个包含三行的文本文件“test.log”:

    one
    two
    three
    
  3. 另外,启动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() 报告的那样,字节 14。

  4. 在第一个 shell 中,将另外两行添加到“test.log”,使其看起来像这样:

    one
    two
    three
    four
    five
    
  5. 回到第二个shell,执行以下代码:

    >>> 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
    >>> 
    

这里我们从os.stat() 看到文件的大小现在是 24 字节,但是以某种方式寻找到文件的末尾仍然指向 14 字节?我已经在 Ubuntu 上使用 Python 2.5 进行了同样的尝试,它可以按我的预期工作。我在我的 Mac 上尝试了 2.5,但得到的结果与 2.6 相同。

我必须在这里遗漏一些基本的东西。有什么想法吗?

【问题讨论】:

  • 如果你使用 os.SEEK_END 而不是文字 2,你会得到不同的结果吗?
  • Macha - 没有区别。问题是我的测试场景...

标签: python macos seek


【解决方案1】:

如何在文件中再添加两行?

大多数文本编辑器都会经历很多这样的操作:

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 命令行选项来处理文件更改但存在同名文件的情况。 (非常适合观看可能会定期轮换的日志文件。)

【讨论】:

    【解决方案2】:

    简短回答:不,你的假设是。

    您的文本编辑器正在创建一个同名的新文件,而不是在原地修改旧文件。您可以在 stat 结果中看到 st_ino 不同。如果你做os.fstat(log.fileno()),你会得到旧的尺寸和旧的st_ino

    如果您想在tail 的实现中检查这一点,请定期比较statfstat 结果中的st_ino。如果它们不同,则会有一个同名的新文件。

    【讨论】:

    • 是的,我错过了正在重新创建文件。谢谢!
    猜你喜欢
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    • 2013-11-04
    • 2011-04-08
    • 1970-01-01
    相关资源
    最近更新 更多