2

メソッドが呼び出されるたびにログファイルから新しい行を読み取る簡単なメソッドを実装しようとしています。

「テール」機能をシミュレートするためのstackoverflow(例:ここ)と他の場所の両方に関するさまざまな提案を見てきました。ほとんどreadline()の場合、ファイルに追加される新しい行を読み取るためにを使用します。十分に単純なはずですが、付属のPython2.6.1を搭載したOSX10.6.4で正しく動作させることはできません。

問題の核心をつかむために、私は次のことを試みました。

  1. 2つのターミナルウィンドウを開きます。

  2. 1つでは、3行のテキストファイル「test.log」を作成します。

    one
    two
    three
    
  3. もう1つは、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
    >>> 
    

    したがって、バイト14で報告されているように、ファイルの最後に到達したtell()ことがわかります。seek(0,2)os.stat()

  4. 最初のシェルで、「test.log」にさらに2行追加して、次のようにします。

    one
    two
    three
    four
    five
    
  5. 2番目のシェルに戻り、次のコードを実行します。

    >>> 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を指していますか?私はPython2.5を搭載したUbuntuで同じことを試しましたが、期待どおりに機能します。Macで2.5を試してみましたが、2.6と同じ結果が得られました。

ここで基本的な何かが欠けているに違いありません。何か案は?

4

2 に答える 2

3

ファイルにさらに2行追加するにはどうすればよいですか?

ほとんどのテキストエディタは、次のような操作を行います。

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; iノード番号はほとんどすべてのテキストエディタで変更されます。)

シェルのリダイレクトを使用してログファイルに追加する>>と、次のように正確に機能します。

$ 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、ファイルが変更された場合を処理するためのコマンドラインオプションがありますが、同じ名前のファイルが存在することに注意してください。(定期的にローテーションされる可能性のあるログファイルを監視するのに最適です。)

于 2010-08-14T11:23:29.303 に答える
2

簡単な答え:いいえ、あなたの仮定はそうです。

テキストエディタは、古いファイルを変更するのではなく、同じ名前の新しいファイルを作成しています。stat結果から、st_inoが異なることがわかります。あなたがするならos.fstat(log.fileno())、あなたは古いサイズと古いものを手に入れるでしょうst_ino

の実装でこれを確認する場合は、との結果をtail定期的に比較してください。それらが異なる場合は、同じ名前の新しいファイルがあります。st_inostatfstat

于 2010-08-14T11:26:40.977 に答える