17

Pythonでファイルが削除または再作成されたかどうかを確認することはできますか?

たとえばopen("file")、スクリプトでを実行し、そのファイルがまだ開いているときに実行するrm file; touch file;と、スクリプトは、すでに削除されていても、古いファイルへの参照を保持します。

4

3 に答える 3

23

fstat開いているファイルのファイル記述子が必要です。

>>> import os
>>> f = open("testdv.py")
>>> os.fstat(f.fileno())
posix.stat_result(st_mode=33188, st_ino=1508053, st_dev=65027L, st_nlink=1, st_uid=1000, st_gid=1000, st_size=1107, st_atime=1349180541, st_mtime=1349180540, st_ctime=1349180540)
>>> os.fstat(f.fileno()).st_nlink
1

このファイルにはリンクが 1 つあるため、ファイル システム内の名前は 1 つです。今それを削除します:

>>> os.unlink("testdv.py")
>>> os.fstat(f.fileno()).st_nlink
0

リンクがなくなったので、開いている間だけ存続する「匿名ファイル」ができました。同じ名前で新しいファイルを作成しても、古いファイルには影響しません。

>>> g = open("testdv.py", "w")
>>> os.fstat(g.fileno()).st_nlink
1
>>> os.fstat(f.fileno()).st_nlink
0

もちろん、最初はそうst_nlinkなる場合もある>1ため、ゼロをチェックすることは完全に信頼できるわけではありません (ただし、制御された設定では、それで十分な場合があります)。stat代わりに、結果を比較することで、最初に開いたパスにあるファイルが、ファイル記述子があるファイルと同じかどうかを確認できます。

>>> os.stat("testdv.py") == os.fstat(f.fileno())
False
>>> os.stat("testdv.py") == os.fstat(g.fileno())
True

(そして、これを 100% 正しくしたい場合は、結果のst_devst_inoフィールドのみを比較する必要があります。stat他のフィールドst_atime、特に呼び出し間で変更される可能性があるためです。)

于 2012-10-02T13:01:50.080 に答える
5

はい。関数を使用してos.stat()、ファイルの長さを確認します。長さがゼロの場合 (または関数が「ファイルが見つかりません」というエラーを返す場合)、誰かがファイルを削除しました。

または、ファイルに何かを書き込む必要があるたびに、ファイルを開く + 書き込む + 閉じることができます。欠点は、ファイルを開く操作がかなり遅いことです。そのため、大量のデータを書き込む必要がある場合、これは問題外です。

なんで?新しいファイルは、開いたままにしているファイルではないためです。簡単に言うと、Unix ファイルシステムには 2 つのレベルがあります。1 つはディレクトリ エントリ (つまり、ファイル名、ファイル サイズ、変更時刻、データへのポインタ) で、2 番目のレベルはファイル データです。

ファイルを開くと、Unix はその名前を使用してファイル データを検索します。その後は、第 2 レベルでのみ動作します。ディレクトリ エントリへの変更は、開いている「ファイル ハンドル」には影響しません。ディレクトリエントリを削除できるのはまさにそのためです。プログラムはそれを使用していません。

を使用するときはos.stat()、ファイル データではなく、ディレクトリ エントリをもう一度確認します。

良い面として、これにより、自分のプログラム以外は誰も見ることができないファイルを作成できます。ファイルを開いて削除し、使用することができます。ファイルのディレクトリ エントリがないため、他のプログラムはデータにアクセスできません。

マイナス面では、あなたが抱えているような問題を簡単に解決することはできません.

于 2012-10-02T12:40:37.440 に答える
3

はい-このinotify機能を使用して、ファイルの変更などを確認できます。そのためのPythonバインディングもあります。inotifyを使用すると、ファイルまたはディレクトリでファイルシステムのアクティビティを監視できます。マニュアルから、次のイベントを検出できます。

IN_ACCESS         File was accessed (read) (*).
IN_ATTRIB         Metadata changed, e.g., permissions, timestamps, extended attributes, link count (since Linux 2.6.25), UID, GID, etc. (*).
IN_CLOSE_WRITE    File opened for writing was closed (*).
IN_CLOSE_NOWRITE  File not opened for writing was closed (*).
IN_CREATE         File/directory created in watched directory (*).
IN_DELETE         File/directory deleted from watched directory (*).
IN_DELETE_SELF    Watched file/directory was itself deleted.
IN_MODIFY         File was modified (*).
IN_MOVE_SELF      Watched file/directory was itself moved.
IN_MOVED_FROM     File moved out of watched directory (*).
IN_MOVED_TO       File moved into watched directory (*).
IN_OPEN           File was opened (*).

ここから解決策をグーグルで検索できますが、全体的なアイデアは得られると思います。もちろん、これはLinuxでのみ機能する可能性がありますが、あなたの質問から、あなたはそれを使用していると思います(とへrmの参照touch)。

于 2012-10-02T12:49:04.977 に答える