2010-08-14 29 views
2

我試圖實現一個簡單的方法,每次調用該方法時從日誌文件中讀取新行。OS X上的Python seek()是否被破壞?

我已經看過在stackoverflow(例如here)和其他地方模擬「尾巴」功能的各種建議;大多數涉及使用readline()來讀取新行,因爲它們被追加到文件中。它應該很簡單,但無法使用Python 2.6.1在OS X 10.6.4上正常工作。

要找到問題的心臟,我試過如下:

  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. 在第一殼,再添兩行「test.log中」,所以它看起來是這樣的:

    one 
    two 
    three 
    four 
    five 
    
  5. 回到第二外殼,並執行以下代碼:

    >>> 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 ??我已經在Python 2.5上用Python 2.5嘗試過,它的工作方式與我的預期相同。我在我的Mac上試用了2.5,但獲得了與2.6相同的結果。

我必須缺少的東西在這裏根本。有任何想法嗎?

+0

如果使用os.SEEK_END而不是文字2,會得到不同的結果嗎? – Macha 2010-08-14 11:11:22

+0

馬查 - 沒有區別。問題是我的測試場景... – 2010-08-14 12:05:00

回答

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檢查它;索引節點號將用於幾乎所有的文本編輯器修改。)

如果使用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命令行選項來處理文件被更改的情況,但存在一個具有相同名稱的文件。 (非常適合觀看可能會週期性旋轉的日誌文件。)

+0

我完全錯過了 - 非常感謝您的澄清! – 2010-08-14 11:58:15

2

簡短回答:不,您的假設是。

您的文本編輯器正在創建一個具有相同名稱的新文件,而不是修改舊文件。你可以在你的stat結果中看到st_ino是不同的。如果你要做os.fstat(log.fileno()),你會得到舊的尺寸和舊的st_ino

如果您想在執行tail時檢查此項,請定期比較statfstat結果中的st_ino。如果它們不同,則會有一個具有相同名稱的新文件。

+0

是的,我錯過了文件被重新創建。謝謝! – 2010-08-14 11:59:05